redis缓存穿透 雪崩 击穿
redis缓存穿透 雪崩 击穿
1)缓存穿透
简介
指客户端请求的数据在缓存中和数据库中都不存在,缓存永远不生效,这些请求都会请求到数据库,多个客户端请求,给持久层的数据库造成很大的压力,这就相当于出现了缓存穿透
解决方案
1.缓存空对象
2.布隆过滤
两种解决方案的优缺点
| 缓存空对象 | 布隆过滤 | |
|---|---|---|
| 优点 | 实现简单,维护方便 | 内存占用较少,没有多余的key |
| 缺点 | 额外的内存消耗,可能会造成短期不一致 | 实现复杂,存在误判 |
思路分析
1.缓存空对象
当客户端访问不存在的数据时,现请求redis,此时redis中没有数据,会访问到数据库,数据库中也没有此数据,这个数据穿透了缓存,直击数据库,数据库承载的并发不如redis高,如果大量的请求同时来访问不存在的数据,这些请求都会访问到数据库,简介解决就是此数据在数据库中不存在,也要存入到redis中去,下次客户端来访问这个不存在的数据,在redis中也能找到这个数据不会进入到缓存了
2.布隆过滤
采用哈希思想来解决,通过一个庞大的二进制数组,走哈希思想去判断当前这个要查询的数据是否存在
若存在,则放行,这个请求会访问redis,哪怕是redis中的数据过期,在数据库中也一定存在,在数据库中查询出来这个数据后,再存入到redis中
若不存在,则直接返回
优点在于节约内存空间,存在误判,原因在于基于哈希思想来实现的,可能存在哈希冲突
2)缓存雪崩
简介
指在同一时段大量缓存的key同时失效或者redis服务宕机,导致大量请求到达数据库,带来巨大压力
解决方案
1.给不同的key的TTL添加随机值
2.利用redis集群提高服务的可用性
3.给缓存业务添加降级限流策略
4.给业务添加多级缓存
3)缓存击穿
简介
缓存击穿页脚热点key问题,就是一个被高并发访问并且缓存较为复杂的key突然失效,无数的请求访问会在瞬间给数据库带来巨大的冲击
解决方案
1.互斥锁
2.逻辑过期
逻辑分析
假设线程1在查询缓存后,应该去查询数据库,然后把这个数据加载到缓存中,现在,只要线程1走完这个逻辑,其他线程就都能从缓存中加载这些数据,假设线程1没有走完,后续的线程2,3,4......同时访问当前这个方法,那么这些线程都不能从缓存中查询到数据,那么这些线程都会同时访问缓存,都查不到,接着同时去访问数据库,同时执行数据库的代码,对数据库访问压力过大。
核心思路
1.互斥锁
相较于原来从缓存中查询不到数据后直接查询数据库而言,现在的方案是 进行查询之后,如果缓存没有查询到数据,则进行互斥锁的获取,获取到互斥锁后,判断是否得到了锁,若没得到,则休眠,过一会再尝试,直到获取到锁为止,才能进行查询。
2.逻辑过期
当客户端开始查询redis时,判断是否命中,如果没有命中则直接返回空数据,不查询数据库,而一旦命中后,将value取出,判断value中的过期时间是否满足,如果没有过期,则直接返回redis中的数据,如果过期,则开启独立线程后直接返回之前的数据,独立线程去重构数据,重构完成后释放互斥锁
解决方案优缺点
| 解决方案 | 优点 | 缺点 |
|---|---|---|
| 互斥锁 | 1.没有额外的内存消耗2.保证一致性3.实现简单 | 1.线程需要等待,性能受影响2.可能有死锁风险 |
| 逻辑过期 | 1.线程无需等待,性能较好 | 1.不保证一致性2.有额外内存消耗3.实现复杂 |
以上内容为本人的经验总结和平时操作的笔记。若有错误和重复请联系作者删除!!感谢支持
浙公网安备 33010602011771号