4. 缓存击穿原理与危害:热点Key失效瞬间,高并发下数据库压力骤增的场景
缓存击穿是缓存系统中一种极具破坏性的失效模式。与缓存雪崩(大量Key同时失效)不同,击穿特指单个热点Key在缓存中失效的瞬间,大量并发请求同时穿透缓存,直接打到后端数据库,导致数据库连接池瞬间耗尽、响应延迟飙升甚至宕机。
4.1 击穿发生的三个必要条件
| 条件 | 说明 | 典型场景 |
|---|---|---|
| 热点Key | 该Key承载了极高比例的读请求,QPS可达数万甚至数十万 | 大促商品详情页、热搜榜单、秒杀商品库存 |
| 缓存失效 | Key到达TTL时间被删除,或被人为淘汰 | 定时过期、LRU淘汰、运维手动清除 |
| 高并发穿透 | 失效瞬间大量请求同时到达,缓存未命中 | 秒杀开启瞬间、整点抢购、热点新闻爆发 |
关键认知:缓存击穿不是“缓存中没有数据”,而是“缓存中曾经有数据,但在高并发窗口期恰好消失”。这比缓存穿透(数据本身就不存在)更危险,因为数据库确实有数据可查,但瞬间流量远超其处理能力。
4.2 击穿发生时的流量瀑布效应
下图展示了热点Key失效后,请求流量如何从缓存层瞬间倾泻到数据库层:
4.3 击穿与雪崩、穿透的对比
| 维度 | 缓存穿透 | 缓存击穿 | 缓存雪崩 |
|---|---|---|---|
| Key数量 | 单个或少量(不存在的数据) | 单个热点Key | 大量Key(成片失效) |
| 根本原因 | 查询不存在的数据 | 热点Key到期失效 | 大量Key同时过期 / 缓存宕机 |
| 数据库压力 | 持续低量无效查询 | 瞬间极高并发 | 持续高并发 |
| 破坏速度 | 缓慢累积 | 瞬间爆发 | 快速蔓延 |
| 典型恢复难度 | 低(加空值缓存即可) | 中(需互斥重建或预热) | 高(需逐层限流降级) |
4.4 真实场景:秒杀商品详情页击穿
以电商秒杀场景为例,某爆款商品的详情页Key product:10001:detail 设置TTL为30分钟。在秒杀开始前,该Key承载了80%的流量。当秒杀开始的瞬间,恰好该Key过期:
- 失效前1秒:缓存命中率99%,数据库QPS约200
- 失效后第1秒:缓存命中率骤降至0%,数据库QPS飙升至15,000
- 失效后第3秒:数据库连接池耗尽,大量请求超时
- 失效后第5秒:应用服务器线程阻塞,上游网关开始报错
实测数据参考:某头部电商平台在一次大促中,因商品详情页热点Key击穿,导致数据库主库CPU从15%瞬间飙升至98%,持续约12秒,期间影响了同库下其他业务的正常查询。事后分析发现,该Key的TTL恰好与秒杀开始时间重合。
4.5 击穿危害的量化评估
缓存击穿的破坏力可以用以下公式估算:
数据库冲击倍数 = 并发请求数 / 数据库最大连接数
示例:
- 热点Key QPS = 20,000
- 数据库连接池上限 = 200
- 冲击倍数 = 20,000 / 200 = 100倍
这意味着数据库需要承受其正常处理能力100倍的瞬时流量,
99.5%的请求将因连接池满而排队或超时。
4.6 击穿发生的典型时间窗口
以下场景最容易触发缓存击穿,需要重点防范:
- 整点/半点失效:大量Key的TTL设置为整点过期,与业务高峰重合
- 热点数据更新后淘汰:后台更新数据后主动删除缓存,导致重建期间出现空窗
- 缓存服务重启:本地缓存(如Caffeine)重启后全部清空,热点Key需要重新预热
- 手动清除缓存:运维或开发在排查问题时误删了热点Key
预防建议:在设计缓存TTL时,应避免热点Key的过期时间与业务高峰(如整点秒杀、定时任务执行)重合。可以采用“基础TTL + 随机偏移”策略,将过期时间分散到更宽的窗口内。