缓存穿透
缓存击穿
缓存雪崩
产生原因
查询一个根本不存在的数据, 缓存层和存储层都不会命中,导致每次请求直接打到数据库, 失去了缓存保护后端存储的意义
redis中某个热点key(访问量很高的key)过期,此时大量请求同时过来,发现缓存中没有命中,这些请求都打到db上了,导致db压力瞬时大增,可能会打垮db
某⼀时刻发⽣⼤规模的缓存失效的情况,例如缓存服务宕机、⼤量 key 在同⼀时间过期,这样的后果就是⼤量的请求进来直接打到 DB 上,可能导致整个系统的崩溃
解决方式
1.缓存空值/默认值
在第一次查询缓存和db都不命中之后,把⼀个空对象或者默认值保存到缓存,之后再访问这个数据,就会从缓存中获取,这样就保护了数据库
2.布隆过滤器。
在db和缓存之前加一个布隆过滤器,做⼀层过滤,作用是判断key是否存在,如果不存在,就不会访问存储。从而避免了对底层存储系统的查询压力。
3.设置可访问的名单(白名单)
使用redis中的bitmaps类型定义一个可以访问的名单,名单id作为bitmaps的偏移量,每次访问和bitmap里面的id进行比较,如果访问的id不在bitmaps里面,则进行拦截,不允许访问
4.进行实时监控
当发现redis的命中率开始急速降低,需要排查访问对象和访问的数据,和运维人员配合,可以设置黑名单限制对其提供服务(比如:IP黑名单)
解决方案
1、加锁更新
缓存中拿不到数据的时候,此时不是立即去db中查询,而是去获取分布式锁(比如redis中的setnx),
拿到锁再去db中load数据,同时更新缓存数据;没有拿到锁的线程休眠一段时间再重试整个获取数据的方法
2、设置热点数据永不过期;
3、预先设置热门数据,适时调整过期时间在redis高峰之前,把一些热门数据提前存入到redis里面,对缓存中的这些热门数据进行监控,实时调整过期时间。
4、提前设置key的缓存失效的时间基础上加上随机数,不会导致同一时间大量key失效
解决方案
1.均匀失效,热点数据永不过期
在原有的key失效时间上加上一个随机值,避免了同一时间大量key过期现象的发生而导致缓存雪崩。
2. 缓存架构的高可用,防止宕机
3. 构建多级缓存,每一级缓存失效时间不同
分布式部署且均匀分布热点数据
如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中。同时,分布式集群可以防止Redis宕机导致缓存雪崩的问题。
5.使用锁或队列
用加锁或者队列的方式来保证不会有大量的线程对数据库一次性进行读写,从而避免失效时大量的并发请求落到底层存储系统上,不适用高并发情况
6. 兜底措施:熔断降级
服务熔断,非核心接口和服务降级