2、缓存击穿问题概述:定义、热点Key失效瞬间、与穿透的区别、对一致性的冲击
2.1 缓存击穿的定义与本质
缓存击穿(Cache Breakdown)是指当缓存中的某个热点 Key 在失效的瞬间,大量并发请求同时穿透缓存,直接涌向后端数据库或服务层,导致数据库瞬间负载激增,甚至引发雪崩效应。
与缓存穿透不同,击穿针对的是存在但恰好失效的热点数据。其本质是:单点失效 + 高并发读的组合攻击。
核心特征:热点 Key 在失效窗口期内,所有请求都无法命中缓存,全部回源到数据库。
2.2 热点 Key 失效瞬间的流量冲击模型
假设一个热点商品 Key product:1001 的 TTL 为 3600 秒。在失效前的瞬间,所有请求都能命中缓存;失效后的第一个请求触发回源,但在此期间涌入的数千个并发请求都会重复回源。
下图展示了热点 Key 失效瞬间的流量冲击路径:
2.3 缓存击穿与缓存穿透的区别
两者虽然名称相似,但成因、影响范围和治理手段完全不同。下表从多个维度进行对比:
| 对比维度 | 缓存击穿 | 缓存穿透 |
|---|---|---|
| 数据是否存在 | 数据真实存在(如热点商品) | 数据根本不存在(如非法ID) |
| 失效原因 | Key 过期 / 被淘汰 / 主动删除 | 缓存未命中 + 数据库无记录 |
| 并发特征 | 高并发集中攻击单个 Key | 大量不同 Key 或随机 Key |
| 数据库影响 | 瞬时峰值极高,持续短 | 持续低效查询,累积压力 |
| 治理核心 | 互斥锁、预热、永不过期 | 布隆过滤器、空值缓存 |
| 典型场景 | 秒杀商品、热搜榜单 | 恶意攻击、爬虫遍历 |
常见误区:很多团队将击穿和穿透混为一谈,使用布隆过滤器治理击穿问题。布隆过滤器只能拦截不存在的数据,对真实存在的热点 Key 失效毫无作用。必须根据问题本质选择正确的保护算法。
2.4 缓存击穿对一致性的冲击
缓存击穿不仅导致性能问题,还会对缓存一致性产生严重冲击,主要体现在以下三个层面:
- 数据不一致窗口扩大:在击穿瞬间,多个线程同时回源数据库,各自执行查询并回写缓存。由于回写顺序不确定,可能导致缓存中写入的是旧版本数据,而数据库已更新为新版本。
- 缓存与数据库的版本冲突:当击穿发生时,如果数据库在并发回源期间发生了更新操作,部分线程可能读到旧数据并覆盖缓存,导致缓存长期落后于数据库。
- 级联失效放大不一致:一个热点 Key 的击穿可能触发关联 Key 的连锁失效。例如商品详情页的击穿导致库存、价格、描述等多个关联 Key 同时回源,回源顺序混乱进一步加剧不一致。
下图展示了击穿导致的数据不一致演化路径:
2.5 击穿场景下的一致性治理挑战
在实际生产环境中,缓存击穿对一致性的冲击往往被低估。以下是三个典型的治理挑战:
| 挑战 | 具体表现 | 影响等级 |
|---|---|---|
| 回源竞态 | 多个线程同时回源,后回源的线程可能用旧数据覆盖新写入的缓存 | 高 |
| 缓存与数据库更新顺序颠倒 | 先更新数据库后删除缓存,但击穿期间删除操作被跳过 | 中 |
| 关联数据不一致 | 商品主数据击穿后,关联的库存、价格、描述等 Key 各自独立回源,导致数据不同步 | 高 |
实践建议:在治理缓存击穿时,不能只关注性能保护(防止 DB 被打垮),还必须同步设计一致性保护策略。推荐采用“互斥锁 + 版本号”的组合方案:互斥锁保证单点回源,版本号保证回写数据的新鲜度。
2.6 本章小结
- 缓存击穿是热点 Key 失效 + 高并发共同作用的结果,与缓存穿透有本质区别。
- 失效瞬间的流量冲击模型显示,所有请求同时回源,数据库负载呈指数级上升。
- 击穿对一致性的冲击主要体现在回源竞态和版本覆盖,导致缓存与数据库长期不一致。
- 治理必须同时兼顾性能保护和一致性保护两个维度,缺一不可。