【Java-Redis】什么是缓存雪崩,如何解决?
·

好的,我来详细讲解缓存雪崩问题及解决方案。先理解概念,再用故事举例说明,最后总结方法论。
一、缓存雪崩的定义
缓存雪崩是指大量缓存数据在同一时间集体过期,导致所有请求直接打到数据库,造成数据库瞬间压力过大而崩溃的现象。
就像高速公路收费站所有闸机同时故障,车辆全部涌向人工窗口导致瘫痪。
二、典型案例场景
某电商平台在双十一零点,10万件商品的缓存同时过期:
缓存层失效 --> 所有查询涌入数据库 --> 数据库QPS暴增 --> 数据库宕机 --> 整个服务不可用
三、核心解决方案
1. 随机过期时间
// 给不同缓存设置不同过期时间
int baseTime = 3600; // 基础1小时
int randomTime = (int)(Math.random() * 600); // 0-10分钟随机偏移
redis.set("product:123", data, baseTime + randomTime);
效果:将缓存失效时间打散,避免集体失效
2. 互斥锁重建
public Product getProduct(String key) {
Product product = redis.get(key);
if (product == null) {
// 获取分布式锁
if (lock.tryLock()) {
try {
// 双重检查
product = redis.get(key);
if (product == null) {
product = db.query(...);
redis.set(key, product, 3600);
}
} finally {
lock.unlock();
}
} else {
// 未获取锁的线程等待重试
Thread.sleep(50);
return getProduct(key);
}
}
return product;
}
效果:限制重建缓存的并发量
3. 二级缓存架构
用户请求 --> 本地缓存(Guava Cache) --> Redis集群 --> 数据库
特点:
- 本地缓存设置不同过期策略(如LRU淘汰)
- Redis集群分片部署(如Codis)
4. 永久缓存+异步更新
// 设置永久缓存但后台异步更新
redis.set("hot:product:123", data);
// 启动定时任务每小时更新
scheduler.scheduleAtFixedRate(() -> {
Product p = db.query(...);
redis.set("hot:product:123", p);
}, 0, 1, TimeUnit.HOURS);
5. 熔断降级
// 使用Hystrix实现熔断
@HystrixCommand(
fallbackMethod = "getProductFallback",
commandProperties = {
@HystrixProperty(name="circuitBreaker.requestVolumeThreshold", value="20")
})
public Product getProduct(String id) { ... }
public Product getProductFallback(String id) {
return defaultProduct; // 返回兜底数据
}
四、真实案例对比
未优化前(某社交APP活动页):
优化后方案:
五、总结方法论

通过以上方法,可以有效预防和应对缓存雪崩问题。实际开发中建议采用多级缓存+随机过期+熔断降级的组合方案,像给系统装上"减震器",即使遇到流量洪峰也能平稳运行。
更多推荐
所有评论(0)