redis缓存穿透、缓存击穿、缓存雪崩问题与解决方案
redis缓存的使用,极大的提升了应用程序的性能,尤其是数据查询方面,但同时也带来了一些问题的,最主要的是数据一致性的问题,从严格意义上讲这个问题无解,如果对数据一致性要求很高就不能使用缓存。
其次是因为某些特殊情况下,缓存失去了预期的功能,导致流量一下子涌入数据库,有可能导致数据库崩溃,对此种场景又进行了细分便有了缓存穿透、缓存击穿、缓存雪崩三种场景问题
缓存穿透
用户想要查询一个数据,但发现访问数据
既不在redis缓存中也没在数据库中
。这种数据库中也找不到对应的数据,就不会写入缓存中,缓存也失去了意义,当有人利用不存在的数据去频繁访问,这样会导致查询请求"跳过缓存"直接去访问数据库,会导致数据库的压力增大,甚至崩溃。这种问题就是缓存穿透
解决方案
-
布隆过滤器
布隆过滤器是一种数据结构,将所有可能查询的参数以hash形式存储,如果查询数据在缓存中存在则让其访问缓存,如果不存在则直接拒绝该请求
-
缓存空对象
当访问的数据在数据库中也查不到时,返回的空对象也存入缓存中,并且设置一个过期时间,到期后再从访问数据库的结果存入缓存中,平衡数据库的访问量
缓存击穿
缓存击穿
是指一个key是热点数据
,不同用户同时(多并发)访问,并且长时间处理这样的高并发的状态,当这个key失效的瞬间,会导致高并发量的请求直接访问数据库,导致数据库压力增大,甚至崩溃
解决方案
-
设置热点数据永不过期
-
添加互斥锁
只让一个线程构建缓存,其他线程等待缓存构建完毕后,重新从缓存中获取结果。单机通过synchronized或者lock来处理,分布式环境采用分布式锁处理
缓存雪崩
缓存雪崩
是指在某一时间段,缓存中的大量热点数据集中过期失效或者redis缓存宕机
,导致请求全部访问数据库,导致数据库压力增大,甚至崩溃
解决方案
-
redis高可用
配置redis集群,避免单台redis宕机导致的缓存雪崩问题
-
限流降级
在缓存失效后,通过加锁或者队列的形式控制访问数据库的线程数量
-
数据预热
在正式部署之前,先把可能访问的数据提前访问一般,这样访问的数据一开始就会加载到缓存中,并且设置key的过期时间是一个随机数,让缓存失效的时间点尽量均匀