Skip to content

缓存穿透与缓存击穿:场景与解决方案

在高并发系统里,缓存是保护数据库和提升延迟表现的关键组件。但当缓存层被异常流量或热点流量冲击时,常见问题主要有两个:缓存穿透缓存击穿。这两个问题经常被混用,治理策略也容易配错。本文聚焦实战场景,给出可直接落地的处理方案。

一、缓存穿透是什么

缓存穿透是指:请求的数据在缓存中不存在,在数据库中也不存在。
如果系统不做防护,这类请求每次都会直接打到数据库。

典型场景(穿透)

  • 恶意请求随机 ID(如订单号、用户 ID),持续查询不存在的数据。
  • 业务参数校验弱,允许大量非法 key 进入查询链路。
  • 爬虫流量异常,触发海量无效查询。

风险(击穿)

  • 数据库 QPS 被无效请求吞噬。
  • 业务正常请求受影响,延迟抖动明显。
  • 在峰值期可能引发雪崩式连锁故障。

二、缓存击穿是什么

缓存击穿是指:某个热点 key在高并发下突然过期,大量并发请求同时回源数据库,形成瞬时冲击。

典型场景(击穿)

  • 秒杀商品详情、热门活动页配置、高频用户信息等热点数据设置了固定 TTL。
  • 同一时间点过期,导致大量请求并发回源。
  • 热点 key 重建逻辑耗时较长,窗口期内数据库压力激增。

风险

  • 数据库或下游服务瞬时打满。
  • 应用线程池阻塞,出现超时和级联失败。
  • 热点请求成功率下降,影响核心链路转化。

三、缓存穿透解决方案

1)参数与权限前置校验

  • 对 ID 格式、长度、业务范围做强校验,不合法直接返回。
  • 对高风险接口加签名校验或鉴权,减少恶意流量直达业务层。

2)布隆过滤器(Bloom Filter)

  • 在缓存前增加布隆过滤器,快速判断 key 是否“可能存在”。
  • 对明显不存在的 key 直接拦截,避免穿透到数据库。

适用点:高并发读场景、数据集合相对稳定、可接受少量误判(误判存在但实际不存在)。

3)缓存空值(Negative Cache)

  • 数据库查询为空时,也写入缓存(如写入 NULL 标记,短 TTL)。
  • 相同无效请求命中空值缓存,不再反复回源。

注意点:

  • TTL 不宜过长,避免影响数据新增后的可见性。
  • 对空值命中率做监控,识别异常流量模式。

4)限流与熔断

  • 针对不存在 key 的请求增加单接口限流、IP 维度限流。
  • 下游压力过高时启用熔断降级,保护核心服务可用性。

四、缓存击穿解决方案

1)热点 key 互斥重建(SingleFlight / 分布式锁)

  • 对热点 key 回源重建加互斥:同一时刻仅允许一个请求回源。
  • 其他请求等待或返回旧值,避免并发打库。

工程实践:

  • 单机可用本地互斥(如 singleflight 思路)。
  • 分布式场景可用 Redis 锁,但要控制锁超时和兜底逻辑。

2)逻辑过期 + 异步刷新

  • 缓存值中存储逻辑过期时间,读到“过期”数据时先返回旧值。
  • 后台异步触发刷新,避免同步请求阻塞和回源风暴。

适用点:对“短时间读到旧值”可容忍的业务(如推荐、榜单、详情页)。

3)TTL 随机化

  • 给同类 key 的 TTL 加随机抖动(如 baseTTL + random(0, x))。
  • 避免大量 key 同时过期造成脉冲式回源。

4)热点预热

  • 在活动开始前预加载热点数据到缓存。
  • 对已识别热点提前刷新,减少首次请求回源。

五、两类问题的对比速记

维度缓存穿透缓存击穿
数据是否存在缓存和数据库都不存在数据存在,但热点 key 过期
压力来源大量无效请求热点并发请求
核心手段布隆过滤器、空值缓存、强校验互斥重建、逻辑过期、TTL 随机化

六、推荐落地组合(实战)

对于电商/资金等高并发场景,可采用分层策略:

  1. 入口层:参数校验 + 风险限流。
  2. 缓存层:空值缓存 + TTL 随机化。
  3. 热点层:互斥重建(SingleFlight/分布式锁)+ 异步刷新。
  4. 观测层:监控空值命中率、热点 key 回源次数、数据库慢查询与错误率。

这样可以同时解决“无效请求冲击”和“热点过期风暴”两类问题。

七、结语

缓存问题本质上不是“加个 Redis 就结束”,而是流量模型、数据模型与系统韧性的综合工程。
把缓存穿透和缓存击穿区分清楚,再按业务特征做组合治理,才能在高峰场景下稳定地保护核心链路。

返回博客列表