剖析Redis缓存穿透、雪崩及其击穿

本文深入探讨了缓存中的三大问题:缓存穿透、缓存雪崩和缓存击穿,分析了它们产生的原因,并提出相应的解决方案。缓存穿透可通过设置无效值或使用布隆过滤器避免,缓存雪崩可以通过设置随机过期时间或使用互斥锁缓解,而缓存击穿则可以采用设置永久有效或使用互斥锁的方法解决。这些策略有助于确保系统的稳定性和高可用性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是缓存穿透?

缓存穿透是指查询一个一不存在的数据。

例如:从缓存redis没有命中,需要从mysql数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。

Redis缓存穿透的解决方案:

  • 在接口层增加校验,不合法的参数直接返回。不相信任务调用方,根据自己提供的 API 接口规范来,作为被调用方,要考虑可能任何的参数传值。
  • 在缓存查不到,DB 中也没有的情况,可以将对应的 key 的 value 写为 null,或者其他特殊值写入缓存,同时将过期失效时间设置短一点,以免影响正常情况。这样是可以防止反复用同一个 ID 来暴力攻击。
  • 正常用户是不会这样暴力功击,只有是恶意者才会这样做,可以在网关 NG 作一个配置项,为每一个 IP 设置访问阈值。
  • 高级用户布隆过滤器(Bloom Filter), 这个也能很好地防止缓存穿透。原理就是利用高效的数据结构和算法快速判断出你这个 Key 是否在 DB 中存在,不存在你 return 就好了,存在你就去查了 DB 刷新 KV 再 return。

什么是缓存雪崩?

在同一个时间,缓存大批量的失效,然后所有请求都打到 DB 数据库,导致 DB 数据库直接扛不住崩了。

例如:电商首页缓存,如果首页的 key 全部都在某一时刻失效,刚好在那一时刻有秒杀活动,那这样的话就所有的请求都被打到了 DB。并发大的情况下 DB 必然扛不住,没有其他降级之类的方案的话,DBA 也只能重启 DB,但是这样又会被新的流量拓机。

 Redis缓存雪崩的解决方案:

  • 批量往 redis 存数据的时候,把每个 key 的失效时间加上个随机数,比如 1-5 分钟随机,这样的话就能保证数据不会在同一个时间大面积失效。 

什么是缓存击穿?

 缓存击穿跟缓存雪崩有些类似,雪崩是大面积缓存失效,导致数据库崩溃,而缓存击穿是一个 key 是热点,不停地扛住大并发请求,全都集中访问此 key, 而当此 key 过期瞬间,持续的大并发就击穿缓存,全都打在 DB 上。就又引发雪崩的问题。

 Redis缓存击穿的解决方案:

  • 把这个热点 key 设置为永久有效。
  • 使用互斥锁,这是比较常用的方法,简单地来说,就是在缓存失效的时候(判断拿出来的值为空),不是立即去查询数据库,而是先使用缓存工具的某些带成功操作返回值的操作(比如 Redis 的 SETNX 或者 Memcache 的 ADD)去 set 一个 mutex key,当操作返回成功时,再进行查询数据库的操作并回设缓存;否则,就重试整个 get 缓存的方法。

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值