缓存穿透、击穿、雪崩解决方案

缓存穿透、击穿、雪崩解决方案

薛定谔的汪

缓存穿透定义 + 成因 + 解决方案 + 实战选型

一、缓存穿透(Cache Penetration)

是什么

大量请求查询根本不存在的数据,缓存查不到,全部打到数据库。

比如:

  • 查询 id = -1 的用户
  • 大量恶意请求不存在的商品
  • 爬虫疯狂扫无效 ID

缓存和数据库都没有,缓存形同虚设 → 穿透

危害

  • DB 压力剧增,甚至打挂
  • 无法通过缓存挡住流量

解决方案

  1. 缓存空值
    • 查不到就缓存 null 或空对象,设置短过期(30s~5min)
    • 简单粗暴,适合小流量场景
  2. 布隆过滤器(Bloom Filter)
    • 把存在的 key 预先放入布隆过滤器
    • 请求先过过滤器:不存在直接返回
    • 适合高并发、恶意攻击场景
  3. 参数校验 + 黑名单
    • 拦截非法 ID、非法请求
    • 网关层直接过滤

二、缓存击穿(Cache Breakdown)

是什么

某个极高并发访问的 key 突然过期,同一瞬间大量请求同时击穿缓存,直接访问数据库。

特点:

  • key 存在,只是过期了
  • 并发极高
  • 只有一个热点 key 出问题

危害

数据库瞬间被打垮,接口雪崩。

解决方案

  1. 互斥锁(分布式锁)

    • 缓存失效时,用 SETNX 加锁
    • 只让一个线程去查 DB 并重建缓存
    • 其他线程等待重试
  2. 热点 key 永不过期

    • 不设置过期时间或设置较大更新时间
    • 后台定时任务异步更新缓存
  3. 逻辑过期

    • 缓存里存过期时间戳
    • 发现快过期,用异步线程更新
    • 前端继续返回旧数据,最终一致性

三、缓存雪崩(Cache Avalanche)

是什么

大量 key 在同一时间集体过期,或 Redis 宕机,导致所有请求瞬间压到数据库。

和击穿区别:

  • 击穿:一个热点 key 过期
  • 雪崩:大片 key 同时失效整个缓存层不可用

危害

数据库直接被压垮,整个系统瘫痪。

解决方案

  1. 过期时间随机化

    • 给过期时间加随机值:3600 ± 300
    • 避免集体过期
  2. 多级缓存

    • Caffeine 本地缓存 + Redis 分布式缓存
    • Redis 挂了,本地缓存还能顶一波
  3. Redis 高可用架构

    • 主从 + 哨兵
    • Redis Cluster 集群
    • 避免单点故障
  4. 服务熔断、限流、降级

    • 流量过载直接熔断,返回兜底数据
    • 保护数据库不被打崩
  5. 互斥锁 + 缓存预热

    • 启动时提前加载热点数据
    • 避免集中重建缓存

四、一张表彻底分清三者

问题 现象 核心原因 关键词
穿透 查询不存在的数据,缓存永远不命中 查无此数据 不存在、恶意请求、布隆
击穿 一个热点 key 过期,并发打库 单个热 key 失效 高并发、热 key、锁
雪崩 大量 key 同时失效 / Redis 挂了 大面积失效 集体过期、集群、熔断

五、实战标准方案

  • 防止穿透:布隆过滤器 + 缓存空值
  • 防止击穿:分布式锁(Redisson)+ 热点 key 永不过期
  • 防止雪崩:过期时间随机 + Redis 集群 + 多级缓存 + 限流降级
  • Title: 缓存穿透、击穿、雪崩解决方案
  • Author: 薛定谔的汪
  • Created at : 2022-05-30 16:39:03
  • Updated at : 2026-03-19 16:56:57
  • Link: https://www.zhengyk.cn/2022/05/30/redis/Redis02/
  • License: This work is licensed under CC BY-NC-SA 4.0.