java面试每日一背 day2
1.什么是缓存击穿?怎么解决?
缓存击穿是指在高并发场景下,某个热点key突然过期失效,此时大量请求同时访问这个已经过期的key,导致所有请求都直接打到数据库上,造成数据库瞬时压力过大甚至崩溃的情况。
解决方案
1. 互斥锁(Mutex Lock)
-  当缓存失效时,不是所有请求都去查询数据库 
-  第一个请求获取锁并查询数据库,其他请求等待 
-  数据库查询完成后更新缓存,后续请求直接从缓存获取 
public Object getData(String key) {Object value = redis.get(key);if (value == null) {if (redis.setnx(key_mutex, 1, 60)) { // 获取锁value = db.get(key);            // 查询数据库redis.set(key, value);          // 更新缓存redis.del(key_mutex);           // 释放锁} else {Thread.sleep(50);               // 等待return getData(key);            // 重试}}return value;
}2. 永不过期策略
-  对热点key设置永不过期(或逻辑过期) 
-  后台异步更新缓存数据 
-  需要额外的维护逻辑来保证数据一致性 
3. 提前续期
-  在key即将过期前,提前异步刷新缓存 
-  避免在过期时刻大量请求涌入 
4. 缓存预热
-  系统启动时或高峰来临前,预先加载热点数据到缓存 
-  特别适合可预测的热点场景 
5. 双缓存策略
-  设置两级缓存:一级缓存(短期)和二级缓存(长期) 
-  一级缓存失效时从二级缓存获取,同时异步更新一级缓存 
最佳实践建议
-  对于极热点数据,优先考虑永不过期+后台刷新策略 
-  一般热点数据使用互斥锁方案,注意锁的粒度要小 
-  结合业务特点选择合适的方案,可能需要多种方案组合使用 
-  监控热点key,对高频访问的数据特殊处理 
2.什么是缓存雪崩?怎么解决?
缓存雪崩是指在同一时间段内,大量缓存key同时失效或缓存服务宕机,导致所有请求直接打到数据库上,造成数据库瞬时压力激增甚至崩溃的现象。
1. 过期时间随机化
-  避免大量key同时过期 
-  在基础过期时间上增加随机值(如1-5分钟的随机数) 
// 设置缓存时添加随机过期时间
int expireTime = 3600 + new Random().nextInt(300); // 3600-3900秒
redis.set(key, value, expireTime);
