2. 缓存基础回顾:缓存穿透、缓存击穿、缓存雪崩

在分布式系统与 Kubernetes 环境下,缓存是保障读性能的核心手段。然而,缓存层在极端流量下会暴露出三类经典故障模式:缓存穿透、缓存击穿与缓存雪崩。理解这三者的成因与解决方案,是后续进行缓存一致性治理与索引重构的前提。

三类缓存异常对比图 缓存穿透 查询不存在的数据 • 请求绕过缓存直达DB • 恶意攻击或空key • DB压力剧增 方案: 1. 布隆过滤器 2. 缓存空对象 3. 参数校验 缓存击穿 热点key过期瞬间 • 单个热点key失效 • 高并发同时回源 • DB瞬间被打穿 方案: 1. 互斥锁/分布式锁 2. 逻辑过期+异步刷新 3. 热点key永不过期 缓存雪崩 大量key同时过期 • 缓存大面积失效 • 流量全部打到DB • 数据库级联崩溃 方案: 1. 过期时间加随机值 2. 多级缓存 3. 限流降级

2.1 缓存穿透

定义:请求查询一个缓存中不存在、数据库中也不存在的数据。由于缓存未命中,每次请求都直接穿透到数据库,导致数据库压力陡增,甚至引发故障。

成因分析

  • 恶意攻击:攻击者构造大量不存在的 key(如负 ID、超长字符串)发起请求。
  • 业务漏洞:查询参数未做合法性校验,导致无效查询。
  • 数据删除:缓存与数据库数据不一致,缓存未及时清理。

经典解决方案

方案原理适用场景注意事项
布隆过滤器将所有可能存在的数据哈希到一个足够大的 bitmap 中,不存在的数据直接拦截数据量固定、误判率可接受存在误判率;不支持删除元素
缓存空对象对查询结果为 null 的 key 也缓存,设置较短过期时间(如 30s)空 key 数量可控可能缓存大量空 key,占用内存
参数校验在 API 网关或业务层对参数进行合法性校验所有场景只能防御格式异常,无法防御业务上不存在的 key
实践建议:在 Kubernetes 环境下,布隆过滤器可以以 Sidecar 模式部署在业务 Pod 中,或通过 Redis 的 BF 模块实现。对于空对象缓存,建议使用 NX + EX 原子操作,避免并发写入。

2.2 缓存击穿

定义:一个热点 key 在缓存过期的一瞬间,大量并发请求同时回源查询数据库,导致数据库压力瞬间飙升。

成因分析

  • 热点 key 过期:某个被高频访问的 key 到达 TTL 时间被删除。
  • 并发回源:在 key 失效的瞬间,所有请求都未命中缓存,同时穿透到数据库。

经典解决方案

方案原理适用场景注意事项
互斥锁(分布式锁)只允许一个线程回源查询,其他线程等待或快速失败并发量极高需考虑锁超时、死锁问题;可能增加响应延迟
逻辑过期 + 异步刷新缓存永不过期,但设置逻辑过期时间;后台线程异步刷新对一致性要求不苛刻实现复杂;存在短暂数据不一致
热点 key 永不过期对识别出的热点 key 不设置 TTL,由后台定时更新热点可预测需要维护热点列表;更新策略需谨慎
Kubernetes 环境下的锁选型:推荐使用 Redis Redlock 或 Etcd 分布式锁。注意锁的粒度要精确到 key 级别,避免锁住整个缓存分区。在 Pod 重启或扩缩容时,锁的持有者可能变化,需做好重试与超时处理。

2.3 缓存雪崩

定义:缓存中大量 key 同时过期,或者缓存节点发生大面积故障,导致大量请求直接打到数据库,引发数据库过载甚至宕机。

成因分析

  • 批量过期:大量 key 设置了相同的过期时间(如统一 1 小时),在同一时刻集体失效。
  • 缓存节点宕机:Redis 集群中某个分片或节点故障,导致该分片上的所有 key 不可用。
  • 缓存重启:Kubernetes 中 Pod 重启或滚动更新导致缓存数据丢失。

经典解决方案

方案原理适用场景注意事项
过期时间加随机值在基础 TTL 上增加随机偏移(如 ±30%)所有场景实现简单,效果显著
多级缓存本地缓存(Caffeine/Guava)+ 分布式缓存(Redis)对延迟敏感需处理本地缓存一致性问题
限流降级对回源请求进行限流,保护数据库高并发场景需配合熔断机制,避免服务雪崩
缓存预热 + 高可用提前加载热点数据;Redis 使用 Sentinel/Cluster 保障高可用生产环境预热策略需与业务对齐
缓存雪崩防护架构 客户端请求 限流 / 熔断 多级缓存(本地 + Redis) 数据库 防护要点 1. 过期时间加随机值 2. 缓存预热 + 高可用 3. 限流保护数据库 4. 本地缓存兜底

2.4 三种异常的对比总结

特征缓存穿透缓存击穿缓存雪崩
触发条件查询不存在的数据单个热点 key 过期大量 key 同时过期 / 节点故障
影响范围单个请求单个热点 key全局或大面积
数据库压力持续低量穿透瞬间高并发持续高并发
核心解决思路拦截无效请求控制并发回源分散过期时间 + 高可用
K8s 环境关注点Sidecar 布隆过滤器分布式锁的 Pod 亲和性Redis 集群 Pod 反亲和
重要提醒:在 Kubernetes 环境下,缓存雪崩的风险更高。因为 Pod 滚动更新、HPA 弹性伸缩、节点故障等场景都可能导致缓存数据批量失效。建议在部署 Redis 时使用 StatefulSet + 持久化存储,并配置 Pod 反亲和策略,避免多个 Redis 实例调度到同一节点。

2.5 本章小结