java - redis 缓存雪崩

缓存雪崩的两种场景

实际开发中,缓存雪崩分两种完全不同的诱因,解决方案也完全不同,必须分开处理。

场景1:大面积缓存key同时过期(最常见)

开发时给大量缓存设置了相同的过期时间,到了时间点所有key集中失效,瞬间所有读请求都绕过Redis,直接查询数据库。

场景2:Redis实例整体不可用(高风险)

Redis服务本身宕机、断网、内存溢出OOM、被误操作关停等,导致整个缓存层彻底不可用,所有请求直接穿透到数据库。

解决方案

1. 针对「大面积key同时过期」的解决方案

核心思路是打散过期时间,避免集中失效

不给同一批数据设置完全相同的过期时间,在基础时间上加一个随机值,把过期时间打散。

java 复制代码
"错误写法:统一1小时过期,容易集中失效"
redisTemplate.opsForValue().set("product:" + productId, product, 3600, TimeUnit.SECONDS);


"正确写法:基础1小时 + 0~300秒随机偏移,错开过期"
int baseTime = 3600;
int randomOffset = new Random().nextInt(300);
redisTemplate.opsForValue().set("product:" + productId, product, baseTime + randomOffset, TimeUnit.SECONDS);

这样所有商品的过期时间分布在59~65分钟之间,不会出现同一时间几万条key同时过期的情况。

2. 分级缓存策略

按数据热度设置不同的过期时间,热点数据长过期/永不过期,冷数据短过期,从根源上减少同时过期的量级。

  • 热点数据(如首页Top100商品、分类导航):设置1天过期,后台异步定时更新,永不过期
  • 普通数据(如普通商品详情):1小时+随机偏移
  • 冷数据(如冷门商品、历史订单):10分钟,过期了也不会有大量请求

3. 缓存预热 + 定时刷新

不要等用户请求触发缓存加载,系统启动或低峰期提前把热点数据加载到缓存;

并且通过定时任务分批异步刷新 缓存,而不是等过期后由用户请求重建。

比如,电商大促前,用脚本提前把所有活动商品缓存写入Redis,过期时间错落设置;凌晨2点低峰期,分批刷新全量商品缓存,避免白天高峰期缓存失效。

开发避坑总结

  1. 永远不要给批量缓存设置完全相同的过期时间,加随机偏移是成本最低的防雪崩手段
  2. 生产环境Redis必须集群部署,禁止单节点
  3. 核心业务一定要做二级缓存(本地 + 远程)和熔断降级,给自己留兜底
  4. 做好监控:Redis命中率、过期key数量、数据库QPS/CPU,这几个指标是雪崩的"预警灯"
  5. 上线前做压测:模拟缓存集中失效、Redis宕机的场景,验证系统的抗压能力
相关推荐
小溪学编程1 小时前
Java ListIterator 接口详解:双向遍历与列表修改的利器
java·开发语言·windows
得物技术1 小时前
企业级 MultiAgent 落地:Plan 模式与主子 Agent 协作|得物技术
java·程序员·架构
程序员清风1 小时前
为什么不推荐走Agent开发?
java·后端·面试
我命由我123451 小时前
Compose Codelab 学习 - Jetpack Compose 中的状态
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
土司大王1 小时前
LeetCode hot100——全排列
java·算法·leetcode
sbjdhjd1 小时前
在 8 字符、字母数字过滤与 PHP 版本差异下复盘临时文件命令执行链 | (8字符绕过)
android·java·开发语言·安全·web安全·数据挖掘·php
秋饼2 小时前
Spring AI 2.0 多模型路由网关:Astra/Sol 到国产模型的智能调度与降级
java·ai·技术分享·后端开发
Wang's Blog2 小时前
Java框架快速入门: Spring Security+OAuth2之密码存储安全进化与实践
java·安全·spring
小七在进步2 小时前
C++入门(3)
android·java·c++