面试中因吹了Redis的牛从而等通知之缓存穿透、缓存击穿、缓存雪崩
Redis之缓穿透
缓存穿透:用户发起请求访问Redis缓存,缓存中没有数据然后去访问数据库,结果数据库也没有这个数据
,也就是说请求最终都会到数据库,从而可能压垮数据库。例子:用一个数据库中ID不存在的用户一直不停的 发送请求,如果有网络黑客利用此漏洞进行攻击数据库可能就会直接崩掉;
解决方案
- 布隆过滤器:将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力
- 存储层不命中后,即使返回的空对象也将其缓存起来,同时会设置一个过期时间,之后再访问这个数据将会从缓存中获取,保护了后端数据源;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22//伪代码
public object GetProductListNew() {
int cacheTime = 30;
String cacheKey = "product_list";
//缓存标记
String cacheSign = cacheKey + "_sign";
String sign = CacheHelper.Get(cacheSign);
//获取缓存值
String cacheValue = CacheHelper.Get(cacheKey);
if (sign != null) {
return cacheValue; //未过期,直接返回
} else {
CacheHelper.Add(cacheSign, "1", cacheTime);
ThreadPool.QueueUserWorkItem((arg) -> {
//这里一般是 sql查询数据
cacheValue = GetProductListFromDB();
//日期设缓存时间的2倍,用于脏读
CacheHelper.Add(cacheKey, cacheValue, cacheTime * 2);
});
return cacheValue;
}
}
### Redis之缓击穿
缓存击穿:缓存在某个时间点突然过期,恰好这个时候并发很多,访问的都是这个Key,因为缓存中没有数据则去请求数据库,造成数据库压力过大可能崩掉;缓存击穿只是针对某一个Key的缓存;
解决方案
- 数据预热
- 加互斥锁
- 数据永不过期
Redis之雪崩
缓存雪崩是指在我们设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DB,DB瞬时压力过重雪崩。
解决方案
- 缓存失效时的雪崩效应对底层系统的冲击非常可怕。大多数系统设计者考虑用加锁或者队列的方式保证缓存的单线 程(进程)写,从而避免失效时大量的并发请求落到底层存储系统上。这里分享一个简单方案就是将缓存失效时间分散开,比如我们可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。
- 数据永不过期
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 九世!
评论