《Redis 高并发八股文:缓存穿透、击穿、雪崩与解决方案》


一、前言:缓存为什么要防“穿、击、崩”

Redis 的引入让系统能“抗流量、快响应”,
但在高并发环境下,缓存失效或查询异常,
会导致请求集中打到数据库,形成雪崩效应。

三大典型问题:

  • 穿透(Penetration) → 查的 key 根本不存在;
  • 击穿(Breakdown) → 热点 key 过期瞬间;
  • 雪崩(Avalanche) → 大量 key 同时过期。

一句话总结:

缓存穿透是“查不到”;
缓存击穿是“突然没了”;
缓存雪崩是“一起没了”。


二、缓存穿透(Cache Penetration)

(1)现象

请求的数据在缓存和数据库中都不存在,
每次请求都绕过 Redis 直击数据库。

当恶意请求或爬虫访问大量不存在的 key 时,
数据库压力骤增,甚至被打垮。

(2)常见原因
  • 用户请求非法 ID(如 -1、0、99999999);
  • 黑客恶意构造不存在 key;
  • 业务逻辑返回 null 但未缓存。
(3)解决方案
方案原理优点
缓存空值查询结果为 null 时也缓存一段时间简单易实现
布隆过滤器(BloomFilter)在缓存前判断 key 是否可能存在高效过滤不存在 key
参数合法性校验限制非法请求降低风险源头

示例代码:

String value = redis.get(key);
if (value == null) {
    if (!bloomFilter.contains(key)) return null; // 过滤
    value = db.query(key);
    if (value == null)
        redis.setex(key, "NULL", 60); // 缓存空值1分钟
    else
        redis.setex(key, value, 3600);
}

三、缓存击穿(Cache Breakdown)

(1)现象

某个热点 key(访问频率极高)突然过期,
在失效瞬间,所有请求同时打到数据库。

(2)典型案例

双十一秒杀场景中,一个商品详情缓存过期,
成千上万请求瞬间查询数据库 → 瞬时高峰宕机。

(3)解决方案
方案思路适用场景
互斥锁(Mutex)第一个请求构建缓存,其他请求等待热点 key 稳定场景
逻辑过期缓存内保存逻辑时间,异步更新高性能系统(如热点数据)
永不过期 + 异步刷新不设置 TTL,由后台定时任务更新高 QPS 低变动数据

示例:逻辑过期 + 异步刷新

class CacheData {
    Object data;
    long expireTime; // 逻辑过期时间
}

CacheData cache = redis.get(key);
if (cache != null && cache.expireTime > System.currentTimeMillis()) {
    return cache.data;
} else {
    // 异步线程刷新
    if (lock.tryLock()) {
        threadPool.submit(() -> {
            Object newData = db.query(key);
            redis.set(key, new CacheData(newData, now+10min));
            lock.unlock();
        });
    }
    return cache.data; // 返回旧值
}

用户永远有数据看,后台异步更新;
稍微复杂,但能应对高并发。


四、缓存雪崩(Cache Avalanche)

(1)现象

大量 key 在同一时间过期或缓存服务器宕机,
所有请求同时访问数据库 → 雪崩式崩溃。

(2)常见原因
  • 定时批量刷新缓存;
  • 使用固定 TTL;
  • Redis 故障。
(3)解决方案
防护措施说明
过期时间随机化TTL = base + random(0, N) 避免同时过期
多级缓存Redis + 本地缓存(Caffeine、Guava)
热点数据永不过期主动更新而非被动过期
服务熔断限流使用 Sentinel / Hystrix / Resilience4j
Redis 集群高可用主从 + 哨兵 / Cluster 模式容灾

示例:

int base = 3600; // 1小时
int random = new Random().nextInt(300);
redis.setex(key, value, base + random); // TTL随机化

五、三者区别一览(面试必背表)

对比项穿透击穿雪崩
问题本质查不存在的数据热点数据过期瞬间大量缓存同时失效
影响范围局部或单 key单热点 key全局多 key
是否可控可通过布隆过滤器预防可用互斥锁或逻辑过期可用随机 TTL 或多级缓存
典型场景恶意请求、空值秒杀商品详情定时刷新、Redis宕机
核心解决策略过滤 + 空值缓存锁 + 逻辑过期随机TTL + 熔断 + 集群

六、面试高频问题与答题模板

问题答案要点
Q1:缓存穿透是什么?查询不存在的数据,缓存和数据库都未命中。
Q2:如何解决缓存穿透?缓存空值、使用布隆过滤器、参数校验。
Q3:缓存击穿是什么?热点 key 过期瞬间并发访问数据库。
Q4:如何解决缓存击穿?加互斥锁、逻辑过期、后台异步刷新。
Q5:缓存雪崩是什么?大量 key 同时过期或 Redis 故障,导致请求打穿数据库。
Q6:如何解决缓存雪崩?TTL 随机化、多级缓存、限流熔断、集群高可用。
Q7:三者的区别?穿透:查不到;击穿:突然没;雪崩:一起没。

结语

缓存的核心目标是:

“让热点留在 Redis,让数据库喘口气。”

但当缓存出现“穿、击、崩”时,
再快的数据库都可能被拖垮。

掌握这三种场景与防护方案,
不仅能在面试中轻松拿下高并发题,
也能在实际项目中写出真正抗压的缓存系统。

更多推荐