Redis 缓存穿透/击穿/雪崩解决方案(附代码)

一、缓存是把双刃剑

Redis 用得好,系统起飞;用不好,半夜救火。本文把缓存最常见的三大问题——穿透、击穿、雪崩——讲透,并给出可直接落地的代码方案。

二、缓存穿透:查不存在的数据

现象:请求一个数据库和缓存都没有的 key,每次都打到 DB。
方案 1:缓存空值

String val = redis.get(key);
if (val == null) {
    val = db.query(key);
    if (val == null) {
        redis.setex(key, 300, ""); // 空值缓存 5 分钟
    }
}

方案 2:布隆过滤器:在缓存前加一层 BloomFilter,不存在的 key 直接拦截。

三、缓存击穿:热点 key 过期瞬间

现象:某个爆款 key 突然失效,海量请求同时打到 DB。
方案:互斥锁(分布式锁)

String val = redis.get(key);
if (val == null) {
    if (redis.setnx("lock:"+key, "1", 10)) { // 拿到锁
        val = db.query(key);
        redis.setex(key, 3600, val);
        redis.del("lock:"+key);
    } else {
        Thread.sleep(50); // 没拿到锁,稍等重试
        return getFromCache(key);
    }
}

四、缓存雪崩:大量 key 同时失效

现象:批量 key 在同一时刻过期,DB 被瞬间压垮。
方案:过期时间加随机抖动

int base = 3600;
int jitter = new Random().nextInt(600); // 0~10分钟随机
redis.setex(key, base + jitter, val);

另外:核心数据可设逻辑过期(不真过期,后台异步刷新)。

五、防坑补充

  • 缓存与数据库一致性:写时先更新 DB 再删缓存(Cache Aside),注意重试。
  • 大 key 拆分:一个 hash 存万级字段会阻塞,拆成多个。
  • 避免热 key 集中:Redis Cluster 分片 + 本地缓存二级兜底。

结语

三大坑记牢”空值、加锁、抖动”六字诀,再配合监控,Redis 就能稳稳扛住高并发。

上一篇 AI 辅助编程实战:Copilot vs Cursor vs Codeium 深度对比
下一篇 Spring Boot 3.x 新特性与升级实操(Java 17 基线)