跳转至

缓存

Web应用和数据库之间加入Redis缓存可以提高程序并发,但也会带来诸多问题。常见的缓存问题有:缓存雪崩、缓存击穿、缓存穿透

1. 缓存雪崩

1.1. 描述

大量缓存数据在同一时间过期(失效)或者+Redis+故障宕机时,如果此时有大量的用户请求,都无法在+Redis+中处理,于是全部请求都直接访问数据库,从而导致数据库的压力骤增,严重的会造成数据库宕机,从而形成一系列连锁反应,造成整个系统崩溃。

1.2. 原因

  • 大量数据同时过期
  • Redis 故障宕机

1.3. 解决办法

大量数据同时过期

  • 均匀设置过期时间
    • 设置缓存过期时间,加上一个随机数。
  • 互斥锁
    • 保证同一时间内只有一个请求来构建缓存
  • 后台更新缓存
    • 频繁地检测缓存是否有效
    • 在业务线程发现缓存数据失效后(缓存数据被淘汰),通过消息队列发送一条消息通知后台线程更新缓存

Redis 故障宕机

  • 服务熔断或请求限流机制
  • 构建 Redis 缓存高可靠集群

2. 缓存击穿

2.1. 描述

缓存中的某个热点数据过期了,此时有大量请求访问了该热点数据,就无法从缓存中获取,直接访问数据库,数据库很容易被高并发请求击垮。

2.2. 原因

频繁反问过期的热点数据

2.3. 解决办法

  • 互斥锁
    • 保证同一时间内只有一个请求来构建缓存
  • 不给热点数据库设置过期时间,后台异步更新或热点数据过期前,提前通知后台线程更新缓存并重新设置过期时间

3. 缓存穿透

3.1. 描述

用户访问的数据,既不在缓存中,也不在数据库中。请求来临时先访问缓存,没有数据,然后再访问数据库,也没有数据,如果这类请求大量涌入,数据库压力急剧上升。

3.2. 原因

一般有2种情况

  • 业务错误操作
    • 缓存和数据库数据均被人删除
  • 黑客恶意攻击
    • 故意使用不存在的数据,大量访问

3.3. 解决办法

  • 限制非法请求
    • 程序中严格校验,判断API请求的合法性。
  • 缓存默认值或空值
    • 当发生缓存穿透情况,针对业务查询的数据,在缓存中创建默认值或空值
  • 使用布隆滤波器快速判断是否存在查询值,避免通过查询数据库判断
    • 布隆滤波器基于哈希函数实现查找,高效查询的同时,也存在哈希冲突的情况(误判)。
    • 查询布隆滤波器数据存在,并不一定证明数据库中一定存在数据。但查询布隆滤波器数据不存在,数据库中一定不存在对应的数据。

参考