题目
分布式缓存中缓存击穿与缓存雪崩的区别及解决方案
信息
- 类型:问答
- 难度:⭐
考点
缓存击穿概念,缓存雪崩概念,分布式缓存解决方案
快速回答
缓存击穿和缓存雪崩是分布式缓存的常见问题:
- 缓存击穿:热点数据失效瞬间,大量请求直接压垮数据库
- 缓存雪崩:大量缓存同时过期,导致数据库请求激增
- 解决方案:
- 击穿:互斥锁、永不过期策略
- 雪崩:随机过期时间、缓存高可用
1. 原理说明
缓存击穿:当某个热点Key突然过期时,海量请求直接穿透缓存访问数据库,导致数据库瞬时压力过大。
缓存雪崩:大量缓存数据在相近时间点集中过期,引发连锁反应式的数据库访问洪峰。
2. 解决方案对比
| 问题类型 | 解决方案 | 实现方式 |
|---|---|---|
| 缓存击穿 | 互斥锁 (Mutex Lock) | 只允许一个线程重建缓存 |
| 永不过期策略 | 逻辑过期时间+后台更新 | |
| 缓存雪崩 | 随机过期时间 | 基础过期时间+随机偏移值 |
| 缓存高可用 | Redis Cluster/Memcached多节点 |
3. 代码示例(Java+Redis)
// 解决缓存击穿 - 互斥锁实现
public String getData(String key) {
String value = redis.get(key);
if (value == null) { // 缓存失效
String lockKey = "lock:" + key;
if (redis.setnx(lockKey, "1", 10)) { // 获取分布式锁
try {
value = db.query(key); // 查数据库
redis.setex(key, 60, value); // 写缓存
} finally {
redis.del(lockKey); // 释放锁
}
} else {
Thread.sleep(50); // 等待重试
return getData(key);
}
}
return value;
}
// 解决缓存雪崩 - 设置随机过期时间
redis.setex(key, 60 + new Random().nextInt(30), value); // 60-90秒随机过期4. 最佳实践
- 击穿防护:热点数据永不过期+异步更新
- 雪崩防护:
- 过期时间 = 基础时间 + 随机偏移(如30%)
- Redis Cluster部署保证高可用
- 监控报警:实时监控缓存命中率
5. 常见错误
- ❌ 对所有Key使用固定过期时间
- ❌ 忽略热点Key的特殊处理
- ❌ 未设置锁超时导致死锁(示例代码中setnx的10秒超时很关键)
6. 扩展知识
- 缓存穿透:查询不存在的数据(解决方案:布隆过滤器)
- 数据一致性:延迟双删策略(先删缓存→更新DB→延时再删缓存)
- 工具推荐:Redisson分布式锁、Spring Cache注解