redis缓存穿透 击穿 雪崩
原创
一、Redis缓存穿透
缓存穿透是指查询一个不存在的数据,由于缓存中没有这个数据,请求会直接到达数据库。这会让数据库承受大量无效查询,进而影响其性能。
二、Redis缓存击穿
缓存击穿是指一个热点数据在缓存中过期,让大量请求同时到达数据库。这会促使数据库瞬间承受巨大的访问压力,大概让数据库崩溃。
三、Redis缓存雪崩
缓存雪崩是指大量缓存数据在同一时间过期,让大量请求到达数据库。这会让数据库压力剧增,甚至大概让系统瘫痪。
四、解决方案
1. 缓存穿透解决方案
针对缓存穿透,可以采用以下方法:
- 接口层提高校验逻辑,对请求参数进行校验,防止恶意请求;
- 使用布隆过滤器,对不存在的数据进行过滤;
- 缓存空对象,即使查询于是为空,也将其缓存起来,设置一个较短的过期时间。
2. 缓存击穿解决方案
针对缓存击穿,可以采用以下方法:
- 热点数据永不过期,或者设置一个较长的过期时间;
- 使用互斥锁,当多个请求同时到达时,只有一个请求能访问数据库,其他请求等待锁释放。
3. 缓存雪崩解决方案
针对缓存雪崩,可以采用以下方法:
- 缓存数据的过期时间设置随机值,避免同时过期;
- 使用熔断降级策略,当缓存雪崩出现时,对部分非核心业务进行降级处理;
- 减成本时间数据库的读写能力,提高数据库的连接数、并发数等。
五、示例代码
1. 缓存穿透示例
public String getCachePenetration(String key) {
// 从缓存中获取数据
String value = getFromCache(key);
if (value != null) {
return value;
}
// 从数据库中获取数据
value = getFromDB(key);
if (value != null) {
// 将数据缓存起来
setToCache(key, value);
} else {
// 缓存空对象
setToCache(key, "", 60);
}
return value;
}
2. 缓存击穿示例
public synchronized String getCacheBreakdown(String key) {
// 从缓存中获取数据
String value = getFromCache(key);
if (value != null) {
return value;
}
// 从数据库中获取数据
value = getFromDB(key);
if (value != null) {
// 将数据缓存起来
setToCache(key, value);
}
return value;
}
3. 缓存雪崩示例
缓存雪崩示例代码与缓存击穿示例代码类似,首要是通过设置缓存过期时间随机值来避免同时过期。