Redis 特性:
- 缓存不命中时被动写(即查不到缓存则去查数据库并写入缓存),且从存储层查不到数据则不写入缓存
Redis 引发问题及解决方案
缓存穿透
解释:
缓存穿透是指查询一个一定不存在的数据(key),导致频繁向底层数据库查询,缓存失去意义。流量过大时,会造成DB宕机
解决方案:
- 布隆过滤器
将所有可能存在的key存到一个足够大的bitmap中,一定不存在的key会直接被bitmap拦截掉,避免继续向DB查询
- 修改redis从DB中查不到数据不写入规则
若向DB查询后返回空数据,仍然把空结果进行缓存,但是过期时间设置较短(<5min)
如何选择:针对一些恶意攻击,攻击带过来的大量key是随机,那么我们采用第一种方案就会缓存大量不存在key的数据。那么这种方案就不合适了,我们可以先对使用布隆过滤器方案进行过滤掉这些key。所以,针对这种key异常多、请求重复率比较低的数据,优先使用第二种方案直接过滤掉。而对于空数据的key有限的,重复率比较高的,则可优先采用第一种方式进行缓存
缓存雪崩
解释:
某一时刻失效(过期)缓存过多 或 Redis宕机,请求全部转发到DB,DB压力过大宕机,重启数据库后,新的流量继续造成数据库宕机
解决方案:
- 尽量保证key过期时间分散
- 分级缓存
第一级缓存失效时,访问二级缓存(两级缓存失效时间不同)
- 热点数据永不过期
物理不过期:key不设置过期时间 ;逻辑不过期:过期时间存储到value中,快过期时,后台构建异步线程进行缓存构建
- 保证缓存高可用
主从+哨兵
- 互斥锁
缓存失效后,通过互斥锁或队列控制读数据写缓存线程数据量,如:一个key只允许一个线程查询,其他对这个key的查询进入线程等待
- 熔断,限流降级
当流量达到一定阈值时,返回提示,不进行DB查询。保证部分用户正常访问,其他用户多次刷新也可请求到数据。
缓存击穿
解释:
某一时刻,某个缓存过期,大量并发请求这个缓存,导致所有请求转发到DB,造成DB宕机