Redis 特性:

  1. 缓存不命中时被动写(即查不到缓存则去查数据库并写入缓存),且从存储层查不到数据则不写入缓存

Redis 引发问题及解决方案

缓存穿透

解释:

缓存穿透是指查询一个一定不存在的数据(key),导致频繁向底层数据库查询,缓存失去意义。流量过大时,会造成DB宕机

解决方案:

  1. 布隆过滤器

将所有可能存在的key存到一个足够大的bitmap中,一定不存在的key会直接被bitmap拦截掉,避免继续向DB查询

  1. 修改redis从DB中查不到数据不写入规则

若向DB查询后返回空数据,仍然把空结果进行缓存,但是过期时间设置较短(<5min)

如何选择:针对一些恶意攻击,攻击带过来的大量key是随机,那么我们采用第一种方案就会缓存大量不存在key的数据。那么这种方案就不合适了,我们可以先对使用布隆过滤器方案进行过滤掉这些key。所以,针对这种key异常多、请求重复率比较低的数据,优先使用第二种方案直接过滤掉。而对于空数据的key有限的,重复率比较高的,则可优先采用第一种方式进行缓存

缓存雪崩

解释:

某一时刻失效(过期)缓存过多 或 Redis宕机,请求全部转发到DB,DB压力过大宕机,重启数据库后,新的流量继续造成数据库宕机

解决方案:

  1. 尽量保证key过期时间分散
  2. 分级缓存

第一级缓存失效时,访问二级缓存(两级缓存失效时间不同)

  1. 热点数据永不过期

物理不过期:key不设置过期时间 ;逻辑不过期:过期时间存储到value中,快过期时,后台构建异步线程进行缓存构建

  1. 保证缓存高可用

主从+哨兵

  1. 互斥锁

缓存失效后,通过互斥锁或队列控制读数据写缓存线程数据量,如:一个key只允许一个线程查询,其他对这个key的查询进入线程等待

  1. 熔断,限流降级

当流量达到一定阈值时,返回提示,不进行DB查询。保证部分用户正常访问,其他用户多次刷新也可请求到数据。

缓存击穿

解释:

某一时刻,某个缓存过期,大量并发请求这个缓存,导致所有请求转发到DB,造成DB宕机

解决方案:

  1. 热点数据永不过期
  2. 在缓存失效后,通过互斥锁 或 队列来控制 读数据写缓存 的线程数量