2. 缓存基础回顾:缓存穿透、缓存击穿、缓存雪崩
在分布式缓存系统中,高并发场景下存在三种经典异常现象:缓存穿透、缓存击穿与缓存雪崩。理解这三者的定义、成因及治理方案,是构建高可用缓存体系的基础。本章从概念、对比到解决方案进行系统梳理。
2.1 三种异常的定义与对比
| 异常类型 | 定义 | 核心成因 | 影响范围 |
|---|---|---|---|
| 缓存穿透 | 请求查询一个缓存和数据库中都不存在的数据,导致每次请求都直接打到数据库。 | 恶意攻击或非法 key 绕过缓存 | 数据库连接耗尽,服务不可用 |
| 缓存击穿 | 某个热点 key 在缓存过期瞬间,大量并发请求同时穿透到数据库。 | 热点 key 过期 + 高并发 | 数据库单点压力骤增,可能宕机 |
| 缓存雪崩 | 大量缓存 key 在同一时间过期,或缓存节点宕机,导致请求全部涌向数据库。 | 批量过期 / 缓存集群故障 | 数据库整体崩溃,系统级故障 |
关键区分:穿透是“查不到”导致绕过缓存;击穿是“单个热点过期”导致并发穿透;雪崩是“大面积过期或节点失效”导致整体崩溃。
2.2 缓存穿透:定义与解决方案
缓存穿透指请求的数据在缓存中不存在(未命中),在数据库中也不存在,导致每次请求都穿透缓存直达数据库。常见于恶意攻击者构造大量不存在的 ID 进行遍历查询。
常见解决方案
- 缓存空对象:将数据库查询为 null 的结果也缓存起来,设置较短的过期时间(如 60 秒),防止同一 key 反复穿透。
- 布隆过滤器(Bloom Filter):在缓存层之前加一层布隆过滤器,用于快速判断 key 是否可能存在。若过滤器判定不存在,则直接拒绝请求,避免查询数据库。
- 参数校验与限流:对请求参数进行合法性校验(如 ID 范围、格式),配合接口限流降低恶意请求的影响。
实践建议:布隆过滤器适合“key 集合相对固定”的场景(如用户 ID 范围已知);缓存空对象实现简单,但需注意空对象过多可能占用内存。
2.3 缓存击穿:定义与解决方案
缓存击穿特指某个热点 key 在缓存过期的瞬间,大量并发请求同时发现缓存失效,全部穿透到数据库查询同一行数据。由于是单点热点,数据库可能瞬间被击垮。
常见解决方案
- 互斥锁(Mutex Key):当缓存失效时,只允许一个线程去数据库加载数据,其他线程等待或返回旧缓存。常用分布式锁(Redis SETNX)实现。
- 逻辑过期 + 异步刷新:缓存中不设置物理过期时间,而是存储一个逻辑过期时间字段。后台线程异步检测并刷新热点 key,保证缓存始终有效。
- 热点 key 永不过期:对极高访问频率的 key 设置为永不过期,配合定时任务主动更新。
注意:互斥锁方案会增加请求延迟(等待锁),适用于“读多写少”的热点数据;异步刷新方案对实时一致性要求较高,需评估业务容忍度。
2.4 缓存雪崩:定义与解决方案
缓存雪崩指缓存层大面积失效(如大量 key 同时过期、缓存节点宕机),导致所有请求直接打到数据库,数据库压力瞬间爆增,引发连锁崩溃。
常见解决方案
- 过期时间随机化:设置缓存过期时间时,在基础时间上增加一个随机偏移量(如 ±30%),避免大量 key 同时过期。
- 缓存集群高可用:采用 Redis Sentinel 或 Redis Cluster 架构,避免单点故障;配合多级缓存(本地缓存 + 分布式缓存)降低雪崩影响。
- 限流与降级:在数据库层前置限流组件(如 Sentinel、Hystrix),当缓存失效时,对数据库请求进行限流,超出阈值的请求直接返回降级结果。
- 预热与双缓存:在流量高峰前提前加载热点数据;使用双缓存策略(主缓存 + 备份缓存),主缓存失效时读取备份缓存。
2.5 三种异常治理对比总览
| 治理维度 | 缓存穿透 | 缓存击穿 | 缓存雪崩 |
|---|---|---|---|
| 核心防御 | 布隆过滤器 / 空对象缓存 | 互斥锁 / 逻辑过期 | 过期时间随机化 / 集群高可用 |
| 数据库保护 | 拒绝非法 key | 单点并发控制 | 限流 + 降级 |
| 实现复杂度 | 低(空对象)~ 中(布隆) | 中(锁)~ 高(异步刷新) | 中(随机化)~ 高(集群) |
| 典型场景 | 恶意遍历 ID | 秒杀商品详情 | 大促批量缓存失效 |
2.6 缓存异常治理流程示意图
下图展示了从请求入口到数据库的完整链路,以及三种异常对应的防御位置:
2.7 综合治理策略总结
在实际分布式缓存系统中,三种异常往往同时存在,需要组合治理:
- 前置拦截层:布隆过滤器 + 参数校验,拦截非法 key 穿透。
- 缓存层加固:热点 key 互斥锁 + 逻辑过期,防止单点击穿;过期时间随机化 + 多级缓存,防止雪崩。
- 数据库保护层:限流、降级、熔断机制,确保数据库在极端情况下不被击垮。
- 监控与告警:实时监控缓存命中率、数据库 QPS、过期 key 分布,及时发现异常苗头。
核心原则:缓存治理不是单一技术选型,而是“预防 + 控制 + 兜底”的体系化设计。穿透靠过滤,击穿靠锁,雪崩靠分散与冗余。