1、缓存穿透
描述:
在查询一个数据时,在缓存中不存在,将去数据库进行查询并且数据库中也不存在数据,使得缓存中一直不会存在数据,导致在请求时每次都会到数据库中进行查询,那么失去了缓存意义。
解决:
将数据库中查询出来为null的数据,写入到缓存中并且设置较短的过期时间。
伪代码:
// 出现问题情况
main(){
String id = "123";
Object obj = Redis.get(id);
if(obj ==null){
// redis获取数据为空,查询数据库
Object dbObj = db.get(id);
if(dbObj!=null){
Redis.set(id,dbObj);
}
return dbObj;
}
return obj;
}
// 解决方案
main(){
String id = "123";
Object obj = Redis.get(id);
if(obj ==null){
// redis获取数据为空,查询数据库
Object dbObj = db.get(id);
if(dbObj!=null){
Redis.set(id,dbObj);
}
// 如果数据库也为null,将null存入缓存,设置较短过期时间(10S)
Redis.set(id,dbObj,10,Seconds);
return dbObj;
}
return obj;
}
2、缓存雪崩
描述:
指设置缓存时的大量的key采用了相同的过期时间,在不同的请求进入时缓存的中大量的key刚好过期,导致请求全部转发到数据库中,使得数据库因为压力过大而崩溃。
解决:
在原有过期时间的基础上,加上一个随机值,比如1~60S,使得key的过期时间减少重复性。
伪代码:
// 模拟从数据库查询到大量不同类型数据
main(){
List<Object> list = db.getData();
// 原有过期时间
long expireTime = 10;
for(Object obj : list){
// 加一个随机值(1~60S)
long newTime= expireTime + (long) (Math.random() * 60);;
Redis.set(key,obj ,newTime,Seconds);
}
}
3、缓存击穿
描述:
对于一些设置了过期时间的key,这些key被访问的频率非常高,在大量请求同时请求某个key时刚好出现过期的情况,那么对这个key的请求都会转发到数据库中,这就是缓存击穿。
解决:
在大量请求访问某个key时,进行加锁
处理,使得其中某一个请求去查询数据库,其他请求进行等待,然后将查询出的数据写入缓存中,再解锁,那么后续的请求就会从缓存中查询到数据,而不是请求数据库。
伪代码:
main(){
// 从redis中获取数据,在请求redis前进行加锁,加锁机制根据实际情况定
// lock()方法为伪代码,表示加锁,只允许一个请求向下执行
lock();
// redis获取数据
Object obj = Redis.get(id);
if(obj == null){
// 请求数据库
Object dbObj = db.get(id);
// 写回到缓存中
Redis.set(id,dbObj);
}
// unlock()方法为伪代码,表示解锁,使得其他请求继续执行
// 在其他请求执行Redis.get(id)时,缓存中已经有了数据,不会再去数据库查询
unlock();
}
4、区别总结
-
穿透
原因:查询redis时查询不到数据,然后去查询数据库也查不到数据,这将导致redis中一直不能缓存到数据。
解决:将查询为null的数据也放入缓存,并且设置较短的过期时间。 -
雪崩
原因:多个key同时失效,高并发下redis查询不到数据,导致大量请求进入到数据库。
解决:对同一类型不同值的key设置不同的失效时间(比如:对手机类型的各条记录(key)设置不同的过期时间)。 -
击穿
原因:对于本该存在于redis中的key,在高并发时key刚好失效,导致大量请求进入到数据库。
解决:让请求加锁
的查询redis,如果没有数据再查询数据库,并且将数据库结果加入到缓存中,后续查询时只能等待上次查询释放锁,再后续请求获取到锁时redis缓存中就已经有了数据,所以不用查询数据库。
5、加锁实现
加锁实现,参考代码《Redis实现分布式锁》
总结:
穿透 — 缓存和数据库中都不存在
数据,导致数据一直无法进行缓存;雪崩 — 大量的不同key同时过期
,导致大量不同请求访问数据库;击穿 — 大量请求同访问某个在缓存中的key
,刚好失效,导致所有请求进入数据库;
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/18150.html