1. 缓存穿透
1.1 问题描述
大量请求同时访问服务器,请求数据:
第一步:服务器去Redis缓存中寻找,但是需要的大量的数据在redis缓存中不存在(redis命中率低)
第二步:服务器在redis中未查询到,转而向数据库进行查询,大量请求涌入数据库,造成数据库崩溃
1.2解决方案
- 对空值做缓存:如果去Redis中查询到的数据为空(无论是否真实在数据库中存在),我们都把这个空结果(null)进行缓存,但需要设置空结果的过期时间(尽量少,最长不得超过5分钟)
- 设置可访问的名单(白名单):使用Bitmaps类型定义一个可以访问的名单,每次访问时和bitmaps中的id进行比较,如果访问id不在bitmaps中,进行拦截
- 布隆过滤器:类似于bitmaps,但是不准确
- 实时监控:当redis命中率持续降低,需要排查访问对象和访问的数据,可以设置黑名单
2. 缓存击穿
2.1问题描述
大量请求同时访问服务器,请求数据:
第一步:redis某个key过期,大量请求访问这个key
第二部:数据库访问压力瞬间增加
2.2 解决方案
- 预先设置热门数据:在redis高峰访问之前,把一些热门数据提前存入到redis中,加大热门数据key的时长
- 实时调整:现场监控,实时调整key的时长
- 使用分布式互斥锁:只允许一个线程重建缓存,其他线程等待重建缓存的线程执行完,重新从缓存获取数据即可。
3.缓存雪崩
3.1 问题描述
第一步:在极少的一段时间内,大量请求查询了key,同时这些key集中过期了
第二步:数据库压力过大服务器崩溃
3.2 解决方案
- 构建多级缓存架构:ngnix + redis + 其他缓存
- 使用锁或者队列
- 设置过期标志:记录缓存数据是否过期,如果过期则通知另外的线程在后台去更新实际key的缓存
- 分散缓存时间:在原有的失效时间上加一个随机值,这样每一个缓存的过期时间的重复率就会降低,很难引起集体失效的事件
4.问题探讨与思考
可以去这篇文章康康:
1.全网最权威!Redis缓存击穿、雪崩、穿透!刷新你的三观!!!
2.【毁三观系列】缓存雪崩、穿透竟该这么答?| 问题竟会一生二、二生四?| 答案为何如此之多?| 系统这么多地方用了缓存?【全网最权威缓存续集(二)】