导言

在分布式系统中,Redis 作为高性能分布式缓存,可有效减轻数据库压力、提升接口响应速度,但高并发场景下,缓存雪崩缓存击穿缓存穿透三类异常易引发系统稳定性问题。

一、缓存雪崩 —— 大量缓存 “集体失效” 的连锁反应

1. 核心定义

缓存雪崩是指某一时间段内,大量缓存数据同时过期失效,或缓存服务(如 Redis 集群)整体不可用,导致原本由缓存承接的高并发请求全部穿透至数据库,引发数据库压力骤增、甚至宕机,进而可能导致整个业务服务雪崩的现象。

核心特征:区别于其他异常,其关键在于 “批量失效 / 整体不可用”,影响范围为 “全局”(而非局部)。

2. 触发条件

缓存雪崩的发生通常源于两类场景,满足任一即可触发:

  • 缓存集中过期:大量缓存数据设置了相同或相近的过期时间(如统一设为 24 小时、固定时间点过期),到期后集体失效,请求失去缓存承接;

  • 缓存服务不可用:Redis 集群因硬件故障、网络波动、内存溢出被系统终止等原因,出现整体宕机或无法访问,导致缓存层完全失效。

3. 解决方案对比

解决方案 实现逻辑 优点 缺点 适用场景
缓存过期时间加随机值 为每个缓存的基础过期时间添加随机偏移量(如基础 1 小时,改为 1h±10 分钟),打散过期时间,避免集中失效 实现简单,仅需修改过期时间逻辑,无额外成本 无法完全杜绝(极端情况仍有小部分缓存集中失效);过期时间精度降低 中小规模系统、缓存数据非强时效需求场景
多级缓存架构 构建 “本地缓存(如 Guava Cache)+ 分布式缓存(Redis)” 分层结构:Redis 缓存失效时,本地缓存可临时承接请求,避免直接穿透至 DB 防护层级多,抗风险能力强,大幅降低 DB 压力 需维护两级缓存一致性(如数据更新时同步清空两级缓存);本地缓存占用应用进程内存 高并发核心业务(如核心接口、高频查询场景)
缓存逻辑永不过期 不设置 Redis 物理过期时间,仅在缓存数据中嵌入 “逻辑过期时间”;业务层查询时判断逻辑过期,若过期则启动异步线程更新缓存(不阻塞当前请求) 无集中过期风险,请求响应速度快(无需等待 DB) 长期占用 Redis 内存(需定期清理无效数据);数据存在短暂不一致(更新完成前仍返回旧数据) 热点数据、对数据一致性要求较低的场景

4. 代码示例(缓存过期时间加随机值・Java)

1
2
3
4
5
6
7
8
// 1. 定义基础过期时间(如1小时,单位:毫秒)
long baseExpireTime = 3600 * 1000;
// 2. 生成-10分钟到+10分钟的随机偏移量(避免集中过期)
Random random = new Random();
long randomOffset = random.nextLong() % 600000; // 600000ms = 10分钟
// 3. 计算最终过期时间,存入Redis
long finalExpireTime = baseExpireTime + randomOffset;
redisTemplate.opsForValue().set("cache:key:" + id, data, finalExpireTime, TimeUnit.MILLISECONDS);

5. 关键监控指标

通过以下指标可量化缓存雪崩的影响,及时发现异常:

  • 缓存命中率:正常场景下应≥90%,雪崩发生时会骤降至 50% 以下;

  • 数据库 QPS:雪崩触发后,DBQPS 会从基线值飙升 2-10 倍(如基线 500→2000+);

  • Redis 服务状态:若为缓存服务不可用,Redis 节点存活数减少、连接超时率骤增;

  • 接口响应时间:核心接口响应时间从正常 50ms 内延长至 500ms 以上,甚至出现超时(1s+)。