缓存穿透、缓存击穿与缓存雪崩:三者的区别与应对策略

举报
1swei 发表于 2026/10/30 08:39:37 2026/10/30
【摘要】 前言在高并发业务场景中,Redis 等缓存中间件几乎是标配。缓存能大幅降低数据库压力,但如果使用不当,同样会引发线上故障。缓存穿透、缓存击穿、缓存雪崩是缓存异常的“三兄弟”,名字相似、成因却完全不同,排查和应对的思路也各不相同。本文把三者一次讲清。 一、缓存穿透:查的是不存在的数据现象:请求查询一个缓存和数据库中都不存在的数据,每次请求都会直接打到数据库。如果这类请求并发量很高,数据库很容...

前言

在高并发业务场景中,Redis 等缓存中间件几乎是标配。缓存能大幅降低数据库压力,但如果使用不当,同样会引发线上故障。缓存穿透、缓存击穿、缓存雪崩是缓存异常的“三兄弟”,名字相似、成因却完全不同,排查和应对的思路也各不相同。本文把三者一次讲清。

一、缓存穿透:查的是不存在的数据

现象:请求查询一个缓存和数据库中都不存在的数据,每次请求都会直接打到数据库。如果这类请求并发量很高,数据库很容易被拖垮。

典型成因

  • 恶意攻击者构造大量不存在的 key 发起请求;
  • 业务代码对不存在的 id、错误的请求参数没有做前置校验。

应对策略

  1. 缓存空对象:查询结果为空时也写入缓存,value 设为空值,并设置一个较短的过期时间(如几分钟),避免频繁回源。
  2. 布隆过滤器:在访问缓存之前先用布隆过滤器判断 key 是否可能存在。布隆过滤器存在一定的误判率,但不会漏判,可以拦截掉绝大多数非法请求。
  3. 参数校验与接口限流:对请求参数做合法性校验,对异常高频的请求做限流降级,从入口处减少无效请求。

二、缓存击穿:热点 key 恰好过期

现象:某个热点 key 恰好过期,此时大量并发请求发现缓存未命中,全部涌向数据库,造成数据库瞬间压力激增。

典型成因

  • 热点 key 设置了统一的过期时间,到点集中失效;
  • 突发流量放大了单 key 过期的影响。

应对策略

  1. 互斥锁重建:缓存未命中时,先尝试获取分布式锁。拿到锁的线程负责查询数据库并回填缓存,其余线程等待或短暂重试,避免并发回源。
  2. 热点 key 永不过期:对真正的热点数据不设置物理过期时间,改由后台任务异步更新,彻底避免过期瞬间的集中回源。
  3. 逻辑过期:在缓存 value 中附带逻辑过期时间。读取时若已逻辑过期,由单个线程异步刷新数据,其余请求仍返回旧值,保证服务的可用性。

三、缓存雪崩:大量缓存集中失效

现象:短时间内大量 key 集中过期,或者缓存集群宕机,导致海量请求同时打到数据库,数据库直接被压垮。

典型成因

  • 批量写入缓存时使用了相同的过期时间;
  • Redis 节点故障、网络抖动导致缓存整体不可用。

应对策略

  1. 过期时间加随机值:在基础 TTL 上增加一个随机偏移量,让 key 的过期时间均匀分散,避免集中失效。
  2. 高可用部署:使用哨兵或集群模式,避免单点故障;做好主从切换和故障演练。
  3. 限流降级与熔断:在缓存不可用时,通过限流、降级、熔断保护数据库,为缓存恢复留出时间。
  4. 多级缓存:在应用本地再加一层本地缓存,即使 Redis 故障,也能承接部分读流量。

四、三者对比

维度 缓存穿透 缓存击穿 缓存雪崩
触发条件 查询不存在的数据 热点 key 过期 大量 key 集中过期或缓存宕机
影响范围 持续消耗数据库 单个热点 key 全量读流量
核心思路 拦截无效请求 单线程重建热点 分散过期、兜底保护
常用手段 布隆过滤器、缓存空值 互斥锁、逻辑过期 随机 TTL、高可用、多级缓存

五、总结

记住三句口诀就够了:穿透查的是“没有的东西”,用布隆过滤器和空值缓存拦截;击穿是“热点过期了”,用互斥锁让只有一个线程去重建;雪崩是“大面积失效”,靠分散过期时间和高可用架构兜底。理解了三者的区别,再遇到缓存异常时,就能快速定位、精准下药。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。