缓存穿透、击穿、雪崩解决方案
缓存穿透定义 + 成因 + 解决方案 + 实战选型。
一、缓存穿透(Cache Penetration)
是什么
大量请求查询根本不存在的数据,缓存查不到,全部打到数据库。
比如:
- 查询 id = -1 的用户
- 大量恶意请求不存在的商品
- 爬虫疯狂扫无效 ID
缓存和数据库都没有,缓存形同虚设 → 穿透。
危害
- DB 压力剧增,甚至打挂
- 无法通过缓存挡住流量
解决方案
- 缓存空值
- 查不到就缓存
null或空对象,设置短过期(30s~5min) - 简单粗暴,适合小流量场景
- 查不到就缓存
- 布隆过滤器(Bloom Filter)
- 把存在的 key 预先放入布隆过滤器
- 请求先过过滤器:不存在直接返回
- 适合高并发、恶意攻击场景
- 参数校验 + 黑名单
- 拦截非法 ID、非法请求
- 网关层直接过滤
二、缓存击穿(Cache Breakdown)
是什么
某个极高并发访问的 key 突然过期,同一瞬间大量请求同时击穿缓存,直接访问数据库。
特点:
- key 存在,只是过期了
- 并发极高
- 只有一个热点 key 出问题
危害
数据库瞬间被打垮,接口雪崩。
解决方案
互斥锁(分布式锁)
- 缓存失效时,用
SETNX加锁 - 只让一个线程去查 DB 并重建缓存
- 其他线程等待重试
- 缓存失效时,用
热点 key 永不过期
- 不设置过期时间或设置较大更新时间
- 后台定时任务异步更新缓存
逻辑过期
- 缓存里存过期时间戳
- 发现快过期,用异步线程更新
- 前端继续返回旧数据,最终一致性
三、缓存雪崩(Cache Avalanche)
是什么
大量 key 在同一时间集体过期,或 Redis 宕机,导致所有请求瞬间压到数据库。
和击穿区别:
- 击穿:一个热点 key 过期
- 雪崩:大片 key 同时失效 或 整个缓存层不可用
危害
数据库直接被压垮,整个系统瘫痪。
解决方案
过期时间随机化
- 给过期时间加随机值:
3600 ± 300秒 - 避免集体过期
- 给过期时间加随机值:
多级缓存
- Caffeine 本地缓存 + Redis 分布式缓存
- Redis 挂了,本地缓存还能顶一波
Redis 高可用架构
- 主从 + 哨兵
- Redis Cluster 集群
- 避免单点故障
服务熔断、限流、降级
- 流量过载直接熔断,返回兜底数据
- 保护数据库不被打崩
互斥锁 + 缓存预热
- 启动时提前加载热点数据
- 避免集中重建缓存
四、一张表彻底分清三者
| 问题 | 现象 | 核心原因 | 关键词 |
|---|---|---|---|
| 穿透 | 查询不存在的数据,缓存永远不命中 | 查无此数据 | 不存在、恶意请求、布隆 |
| 击穿 | 一个热点 key 过期,并发打库 | 单个热 key 失效 | 高并发、热 key、锁 |
| 雪崩 | 大量 key 同时失效 / Redis 挂了 | 大面积失效 | 集体过期、集群、熔断 |
五、实战标准方案
- 防止穿透:布隆过滤器 + 缓存空值
- 防止击穿:分布式锁(Redisson)+ 热点 key 永不过期
- 防止雪崩:过期时间随机 + Redis 集群 + 多级缓存 + 限流降级
- Title: 缓存穿透、击穿、雪崩解决方案
- Author: 薛定谔的汪
- Created at : 2022-05-30 16:39:03
- Updated at : 2026-03-19 16:56:57
- Link: https://www.zhengyk.cn/2022/05/30/redis/Redis02/
- License: This work is licensed under CC BY-NC-SA 4.0.