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宕机的场景,验证系统的抗压能力
相关推荐
xcl09254 小时前
北京24小时自助健身房系统软件开发实战:从架构到部署全流程指南
java·spring boot·架构
一 乐6 小时前
动漫书销售商城|基于springboot + vue动漫书销售商城(源码+数据库+文档)
java·数据库·vue.js·spring boot·毕业设计
卓怡学长6 小时前
w214基于jsp知道特产网
java·intellij-idea
步行cgn6 小时前
Spring 注解使用详解
java·spring
一条小小yu7 小时前
Spring IoC的理解
java·后端·spring
落魄实习生7 小时前
Agent Scope Java 2.x 系列【7】工具使用
java·开发语言·ai
旺仔学长 哈哈7 小时前
springboot钓鱼爱好者交流平台APP设计与实现
java·spring boot·mysql·充电桩管理系统
自强的小白9 小时前
核心功能(Service接口)
java·mybatis
乌暮9 小时前
深入理解 Java 泛型:把「万能盒子」用对、用稳
java·开发语言·后端·学习