缓存击穿、穿透、雪崩分别是什么意思?怎么解决?

缓存相关问题是高并发系统中常见的性能挑战,缓存击穿、缓存穿透、缓存雪崩分别指不同的异常访问场景。下面分别说明其含义、成因与解决方案:


✅ 一、缓存击穿(Cache Breakdown)

❓定义

某个热点 key 在某一瞬间失效,而此时有大量并发请求访问这个 key,由于缓存失效,请求会同时打到数据库,可能造成数据库压力骤增,甚至崩溃。

典型场景

例如商品详情页中一个高频商品的缓存到期,此时大量用户访问,就会同时请求数据库查询该商品信息。

✅解决方案

  1. 互斥锁(加锁控制)

    • 在缓存未命中时,只允许一个线程去查询数据库并写入缓存,其他线程等待或稍后重试。

    • Redis 分布式锁、ReentrantLock + 双重检查(Double Check)是常见做法。

  2. 热点数据永不过期(或延迟异步刷新)

    • 对于热点数据设置超长 TTL,同时后台定时异步刷新缓存内容。

  3. 异步更新(如通过消息队列)

    • 读取请求不直接更新缓存,而是将 miss 的 key 投递到 MQ,由后台异步更新缓存。


✅ 二、缓存穿透(Cache Penetration)

❓定义

请求的数据在缓存和数据库中都不存在,用户请求会每次都打到数据库,形成大量无效访问。

典型场景

攻击者大量请求数据库中不存在的用户ID、商品ID等,绕过缓存防线,击穿数据库。

✅解决方案

  1. 缓存空对象

    • 对于数据库不存在的数据,也缓存一个空值(如 NULL 或特殊标记),并设置较短 TTL。

  2. 布隆过滤器(Bloom Filter)

    • 在缓存前使用布隆过滤器拦截不存在的数据请求,节省缓存和数据库资源。

    • 适合已知 key 空间有限、较为静态的场景(如商品ID、用户ID等)。

  3. 接口限流+身份校验

    • 对恶意请求进行黑名单、IP 限流、验证码校验等手段防护。


✅ 三、缓存雪崩(Cache Avalanche)

❓定义

大量缓存集中在某一时间失效,导致请求全部落到数据库,产生“雪崩”效应。

典型场景

缓存预热脚本同时设置了很多缓存 TTL 为 10 分钟,当这批缓存同时到期时,会对数据库造成集中冲击。

✅解决方案

  1. 随机过期时间

    • 为缓存的 TTL 加上一定的随机值,避免集中失效。

      long ttl = 3600 + ThreadLocalRandom.current().nextInt(300); // 3600~3900秒
      
  2. 预热与分批加载

    • 缓存预热时分批加载,避免所有 key 同时过期。

  3. 热点数据永不过期 + 后台定期刷新

    • 参考击穿中的“异步更新”策略。

  4. 多级缓存架构

    • 结合本地缓存(如 Caffeine)+ Redis,分层抗压。


总结对比

问题类型 定义 影响 典型原因 常见解决
缓存击穿 热点 key 失效被高并发请求打穿 数据库被冲垮 缓存 TTL 到期 加锁互斥、永不过期、异步更新
缓存穿透 查询数据不存在,缓存和数据库都无 数据库压力 恶意请求/异常 ID 空对象缓存、布隆过滤器、限流
缓存雪崩 大量缓存同时失效 数据库雪崩 TTL 设置相同 TTL 随机化、分批过期、后台刷新

需要我帮你写一段 Spring Boot 或 Redis 相关的实际代码示例来解决某一类缓存问题吗?

你可能感兴趣的:(分布式/中间件,缓存)