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宕机的场景,验证系统的抗压能力
相关推荐
文丑颜不良啊12 分钟前
LeetCode2521~2540题目解析
java·leetcode
杨凯凡13 分钟前
Spring Framework 7 HTTP Interface 实战:声明式 RestClient、超时与测试
java·spring·http
吴名氏.29 分钟前
Java转AI Agent教程(第十二周)检索与切分
java·开发语言·人工智能·ai·ai agent
瑞雪兆丰年兮1 小时前
JavaWeb-day10-SpringBootWeb案例
java·开发语言·javaweb·web
Rain的Java大神之路1 小时前
你背的Spring答案,全是5.x时代的:7.0.8源码一翻,80%的博客都过时了
java·后端·面试
这个昵称不容易2 小时前
考试报名系统的设计与实现(SpringBoot + MySQL + Vue 三角色平台)
java·springboot·毕设
Adellle2 小时前
设计模式指南 (Java 版) ㊁
java·开发语言·设计模式
特立独行的猫A3 小时前
cj-tauri:用仓颉写桌面与鸿蒙 PC 应用
java·后端·python
Lonely丶墨轩3 小时前
从一个 404 到负数 ID:第三方接口开发中的几次排错
java
聪明的笨猪猪3 小时前
实际工程问题:AI生成MyBatis批量操作的SQL超限与性能雪崩
java·经验分享·面试·ai编程