缓存穿透、缓存击穿与缓存雪崩:三者的区别与应对策略
【摘要】 前言在高并发业务场景中,Redis 等缓存中间件几乎是标配。缓存能大幅降低数据库压力,但如果使用不当,同样会引发线上故障。缓存穿透、缓存击穿、缓存雪崩是缓存异常的“三兄弟”,名字相似、成因却完全不同,排查和应对的思路也各不相同。本文把三者一次讲清。 一、缓存穿透:查的是不存在的数据现象:请求查询一个缓存和数据库中都不存在的数据,每次请求都会直接打到数据库。如果这类请求并发量很高,数据库很容...
前言
在高并发业务场景中,Redis 等缓存中间件几乎是标配。缓存能大幅降低数据库压力,但如果使用不当,同样会引发线上故障。缓存穿透、缓存击穿、缓存雪崩是缓存异常的“三兄弟”,名字相似、成因却完全不同,排查和应对的思路也各不相同。本文把三者一次讲清。
一、缓存穿透:查的是不存在的数据
现象:请求查询一个缓存和数据库中都不存在的数据,每次请求都会直接打到数据库。如果这类请求并发量很高,数据库很容易被拖垮。
典型成因
- 恶意攻击者构造大量不存在的 key 发起请求;
- 业务代码对不存在的 id、错误的请求参数没有做前置校验。
应对策略
- 缓存空对象:查询结果为空时也写入缓存,value 设为空值,并设置一个较短的过期时间(如几分钟),避免频繁回源。
- 布隆过滤器:在访问缓存之前先用布隆过滤器判断 key 是否可能存在。布隆过滤器存在一定的误判率,但不会漏判,可以拦截掉绝大多数非法请求。
- 参数校验与接口限流:对请求参数做合法性校验,对异常高频的请求做限流降级,从入口处减少无效请求。
二、缓存击穿:热点 key 恰好过期
现象:某个热点 key 恰好过期,此时大量并发请求发现缓存未命中,全部涌向数据库,造成数据库瞬间压力激增。
典型成因
- 热点 key 设置了统一的过期时间,到点集中失效;
- 突发流量放大了单 key 过期的影响。
应对策略
- 互斥锁重建:缓存未命中时,先尝试获取分布式锁。拿到锁的线程负责查询数据库并回填缓存,其余线程等待或短暂重试,避免并发回源。
- 热点 key 永不过期:对真正的热点数据不设置物理过期时间,改由后台任务异步更新,彻底避免过期瞬间的集中回源。
- 逻辑过期:在缓存 value 中附带逻辑过期时间。读取时若已逻辑过期,由单个线程异步刷新数据,其余请求仍返回旧值,保证服务的可用性。
三、缓存雪崩:大量缓存集中失效
现象:短时间内大量 key 集中过期,或者缓存集群宕机,导致海量请求同时打到数据库,数据库直接被压垮。
典型成因
- 批量写入缓存时使用了相同的过期时间;
- Redis 节点故障、网络抖动导致缓存整体不可用。
应对策略
- 过期时间加随机值:在基础 TTL 上增加一个随机偏移量,让 key 的过期时间均匀分散,避免集中失效。
- 高可用部署:使用哨兵或集群模式,避免单点故障;做好主从切换和故障演练。
- 限流降级与熔断:在缓存不可用时,通过限流、降级、熔断保护数据库,为缓存恢复留出时间。
- 多级缓存:在应用本地再加一层本地缓存,即使 Redis 故障,也能承接部分读流量。
四、三者对比
| 维度 | 缓存穿透 | 缓存击穿 | 缓存雪崩 |
|---|---|---|---|
| 触发条件 | 查询不存在的数据 | 热点 key 过期 | 大量 key 集中过期或缓存宕机 |
| 影响范围 | 持续消耗数据库 | 单个热点 key | 全量读流量 |
| 核心思路 | 拦截无效请求 | 单线程重建热点 | 分散过期、兜底保护 |
| 常用手段 | 布隆过滤器、缓存空值 | 互斥锁、逻辑过期 | 随机 TTL、高可用、多级缓存 |
五、总结
记住三句口诀就够了:穿透查的是“没有的东西”,用布隆过滤器和空值缓存拦截;击穿是“热点过期了”,用互斥锁让只有一个线程去重建;雪崩是“大面积失效”,靠分散过期时间和高可用架构兜底。理解了三者的区别,再遇到缓存异常时,就能快速定位、精准下药。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)