TL;DR(30 秒扫完)
- 三失效 = 三种根因:穿透=无效 key、击穿=热点 key 失效、雪崩=批量失效
- 防御分层:入口校验 → 布隆过滤器 → 互斥锁/逻辑过期 → TTL 抖动 → 高可用 → 多级缓存 → 限流熔断
- 布隆过滤器:预加载有效 ID,误判率 1%,不支持删除,需定期重建
- 逻辑过期:值里存 expireTime,物理 TTL 永不过期,适合高并发容忍读旧
关键结论
结论 A三问题常同时出现(如电商秒杀),防御体系必须分层叠加
结论 B布隆过滤器有静态限制,新增数据要同步更新,误判率权衡精度和内存
结论 C雪崩根因是批量失效 + 基础设施故障,单靠应用层防御不够,需要 Redis 高可用
结论 D缓存空值是最后兜底手段,但要设短 TTL 防缓存爆炸
完整讲解(费曼四步)
STEP 1 · 概念
缓存三失效是缓存系统中的三种典型故障模式:- 穿透:请求不存在的数据,每次都打到 DB
- 击穿:热点 key 过期,瞬间并发穿透到 DB
- 雪崩:大批 key 同时过期或 Redis 整体不可用,DB 被打爆
STEP 2 · 大白话
图书馆比喻:- 穿透:有人反复查一本图书馆根本没有的书,每次都去书架找一遍 → 需要"不存在书目黑名单"
- 击穿:一本热门书被借走还没还,几百人同时来借 → 需要"预借排队机制"
- 雪崩:图书馆突然停电,所有书都借不了,大家全部涌到出版社 → 需要"备用图书馆"
STEP 3 · 底层
缓存穿透(Cache Penetration)
根因:数据不存在 → 无 key 可存 → 无缓存可查 方案分层:| 层级 | 方案 | 说明 |
|---|---|---|
| 1 | 入口参数校验 | 参数校验、鉴权、限流,提前拦截非法 ID |
| 2 | 布隆过滤器 | 预加载所有有效 ID,误判率可控(推荐 1%) |
| 3 | 空值缓存 | DB 查不到缓存 null,TTL 短(30s-1min) |
| 4 | 风控兜底 | 同一 IP 高频无效请求 → 封禁 / 验证码 |
- 启动时把所有有效 ID 载入 Bloom Filter
- 请求先判存在性,不存在直接返回
- 不支持删除,新增数据要同步更新
- 误判率权衡:1% 误判率需要约 1.4 倍空间
- 动态更新:用 Count-Min Sketch 或 RedissonBloom 支持动态扩容
缓存击穿(Cache Breakdown)
根因:单热点 key 过期 + 并发请求 方案三档:| 方案 | 机制 | 适用 |
|---|---|---|
| 互斥锁重建 | SET key_lock NX PX 10000,拿到锁查 DB 回填,其余等待 | 中等并发 |
| 逻辑过期 | 值结构存 expireTime,物理 TTL 永不过期,发现过期后异步重建 | 高并发容忍读旧 |
| 永不过期 + 后台刷新 | 定时任务提前刷新热点数据 | 核心热点数据 |
- 用 Redis 的
SETNX实现互斥锁 - 锁超时时间要 > 业务耗时(一般 10s)
- 其他线程短轮询读缓存,避免阻塞
- 值结构:
{data: "...", expireTime: 1700000000} - 物理 TTL 设为永不或超长(如 7 天)
- 发现
expireTime < now后异步重建 - 容忍短暂读旧,但避免并发穿透
缓存雪崩(Cache Avalanche)
根因:批量失效 + 基础设施故障 方案分层:| 层级 | 方案 | 说明 |
|---|---|---|
| 1 | TTL 加随机抖动 | TTL = base + random(0, delta),避免同时过期 |
| 2 | Redis 高可用 | 主从 + Sentinel / Cluster,故障自动切换 |
| 3 | 多级缓存 | 本地缓存(Caffeine)+ Redis + DB |
| 4 | 限流熔断 | Sentinel / Hystrix,DB 压力大时快速失败 |
| 5 | 预热 | 定时刷新热点数据,重启前主动加载 |
- 例:所有商品详情 TTL = 3600 + random(0, 3600)(1-2 小时)
- 避免整点大量 key 同时过期
- L1:Caffeine(本地,TTL 极短 1-5s)
- L2:Redis(分布式,TTL 1-10min)
- L3:DB(最终一致)
- 一致性靠 Cache-Aside + 发布订阅
STEP 4 · 简化
一句话总结:穿透防无效、击穿防单点、雪崩防批量。防御分层叠加,布隆+互斥+抖动+高可用+多级+熔断。 记忆口诀:- 穿透 → 布隆过滤器 + 空值缓存
- 击穿 → 互斥锁 + 逻辑过期
- 雪崩 → TTL 抖动 + 高可用 + 多级缓存 + 熔断
常见误区
说"布隆过滤器能支持删除"
标准布隆过滤器不支持删除,需用 Count-Min Sketch
说"逻辑过期完全无副作用"
容忍短暂读旧,不适用于强一致场景
说"空值缓存可以 TTL 很长"
恶意请求可撑爆缓存,TTL 要短(30s-1min)
说"雪崩只要加 TTL 抖动就能防"
TTL 抖动防批量失效,但防不了 Redis 宕机,需要高可用 + 多级缓存
延伸追问
布隆过滤器不支持删除怎么办?数据新增如何同步?
Count-Min Sketch 支持计数减一;新增数据写入时同步 hash 进过滤器;或用 RedissonBloom 支持动态扩容
逻辑过期如何避免时钟漂移导致大量过期?
用 Redis 服务端时间;或改用 Redis TTL 但配合互斥锁
多级缓存的一致性问题怎么解决?
Cache-Aside + 发布订阅;本地缓存 TTL 极短(秒级);业务容忍短暂不一致
秒杀场景如何设计缓存防御体系?
预热库存到 Redis + Lua 原子扣减 + 布隆过滤 + 消息削峰 + 空单降级
Redis 集群整体宕机,你的系统如何优雅降级?
熔断打开 + 静态兜底数据 + 排队限流 + 前端提示
速查表
三失效: 穿透(无效) / 击穿(单点) / 雪崩(批量)
穿透防御: 入口校验 → 布隆过滤器 → 空值缓存 → 风控
击穿防御: 互斥锁 / 逻辑过期 / 永过期+后台刷新
雪崩防御: TTL抖动 → 高可用 → 多级缓存 → 限流熔断
布隆: 预加载+误判率1%+不支持删除+需定期重建
逻辑过期: 值存expireTime+物理TTL永不+容忍读旧
空值缓存: TTL 30s-1min+防缓存爆炸
Anki 候选卡片
Q: 缓存三失效的根因分别是什么?
A: 穿透=无效 key、击穿=热点 key 失效、雪崩=批量失效
Q: 布隆过滤器的限制?
A: 不支持删除、新增数据需同步更新、有误判率(推荐 1%)
Q: 缓存击穿三档方案?
A: 互斥锁重建、逻辑过期、永不过期+后台刷新
Q: 空值缓存的 TTL 设多久?
A: 30s-1min,防止恶意请求撑爆缓存
Q: 缓存雪崩的 5 层防御?
A: TTL 抖动 → 高可用 → 多级缓存 → 限流熔断 → 预热
关联题目
关联知识
三失效根因不同:穿透=无效 key、击穿=热点 key 失效、雪崩=批量失效
三失效像三个不同问题:穿透是查不存在的人;击穿是抢一个爆款;雪崩是全场断电
✦ 记 忆 口 诀 ✦
根因不同防御必须差异化:入口校验→布隆→互斥→TTL 抖动→高可用
关键可视化
三失效对比
flowchart TB C["缓存失效"] --> P["穿透<br/>无效 key<br/>每次都打到 DB"] C --> B["击穿<br/>热点 key 过期<br/>瞬间并发穿透"] C --> A["雪崩<br/>批量 key 同时过期<br/>或 Redis 整体宕机<br/>DB 被打爆"]
防御分层体系
flowchart LR L1["1.入口校验<br/>参数合法性"] --> L2["2.布隆过滤器<br/>预加载有效 ID"] L2 --> L3["3.互斥锁/逻辑过期<br/>热点 key 只让一个请求"] L3 --> L4["4.TTL 抖动<br/>随机延迟防批量失效"] L4 --> L5["5.Redis 高可用<br/>哨兵/Cluster"] L5 --> L6["6.多级缓存<br/>本地 Caffeine"] L6 --> L7["7.限流熔断<br/>保护 DB"]
布隆过滤器
flowchart LR
I["请求 key"] --> B{"布隆过滤器"}
B -->|可能存在| C["查缓存/DB"]
B -->|一定不存在| R["直接返回"]
subgraph 特点
F1["误判率 1%"]
F2["不支持删除"]
F3["需定期重建"]
F4["内存极省"]
end知识关系
⬆️ 前置(Prerequisite)
redis-single-thread🔄 延伸(Extends)
暂无
🎯 概念
📏 规则
⚠️ 误区
🔍 追问
✨ 口诀
共 0 张卡,点击翻面