Redis缓存穿透雪崩击穿的解决方案
2025年Java面试宝典最新版:
点击下载
(包含Redis高频考点解析,助你快速掌握缓存问题的核心解法!)
什么是缓存穿透?
缓存穿透是指查询一个数据库中不存在的数据,导致请求直接打到数据库。比如攻击者伪造大量不存在的订单ID查询,绕过Redis缓存,直接穿透到MySQL层。这种现象会导致数据库负载激增,甚至崩溃。
解决方案1:缓存空对象
当查询数据库不存在的数据时,在Redis中存储一个空值(如key: null),并设置较短的过期时间(如5分钟)。下次请求命中Redis时直接返回空结果,避免重复穿透数据库。但要注意空对象过多可能占用内存,需结合业务场景调整过期时间。
解决方案2:布隆过滤器
布隆过滤器(Bloom Filter)是一种概率型数据结构,可以快速判断某个元素是否可能存在于集合中。将所有有效数据的ID存入布隆过滤器,请求到达时先经过过滤器判断:
- 如果不存在,直接返回空结果;
- 如果可能存在,再去查缓存或数据库。
布隆过滤器的优点是内存占用小,但存在一定误判率(可通过调整参数降低)。

什么是缓存雪崩?
缓存雪崩是指大量缓存数据同时过期,导致大量请求直接打到数据库。比如某个时刻大量缓存Key集中失效,数据库瞬间承受高并发压力,可能引发连锁崩溃。
解决方案1:随机过期时间
给缓存Key的过期时间增加随机值。例如原本统一设置60分钟过期,可以改为60 + random(0, 10)分钟。通过分散过期时间,避免大量Key同时失效。
解决方案2:多级缓存架构
采用多级缓存机制,例如本地缓存(Caffeine) + 分布式缓存(Redis)。即使Redis部分数据失效,本地缓存仍能缓解数据库压力。但需要注意本地缓存与分布式缓存的一致性。
解决方案3:热点数据永不过期
对访问频率高的热点数据,采用“逻辑过期”策略。即Redis中存储数据时不设置过期时间,但后台异步更新数据。例如每隔30分钟从数据库拉取最新数据更新到Redis。

什么是缓存击穿?
缓存击穿是指某个热点Key突然失效,同时有大量并发请求访问这个Key,导致请求全部穿透到数据库。例如秒杀活动中商品详情Key失效,瞬间被数万请求击穿。
解决方案1:互斥锁(Mutex Lock)
当缓存失效时,只允许一个线程去查数据库,其他线程等待。可以通过Redis的SETNX命令实现分布式锁:
- 线程A发现缓存失效,尝试获取锁;
- 获取成功则查询数据库并回填缓存;
- 其他线程等待锁释放后直接从缓存读取。
解决方案2:逻辑过期
缓存数据不设置物理过期时间,而是在数据中存储一个逻辑过期时间字段。当发现数据逻辑过期时,触发异步线程更新缓存,当前线程返回旧数据。这种方式能保证高可用性,但数据有一定延迟。
实战经验与优化建议
- 监控与告警:对缓存命中率、数据库QPS设置监控阈值,及时发现问题。
- 压测验证:定期模拟高并发场景,验证缓存策略的可靠性。
- 熔断降级:在数据库压力过大时,启用熔断机制,返回兜底数据(如默认商品信息)。

如果大家在准备面试时需要面试鸭会员,可以通过面试鸭返利网找我,返利25元!用省下的钱买杯咖啡,刷题更提神哦~


