什么情况引起redis缓存穿透(击穿和雪崩以及解决方案)
一:redis雪崩redis雪崩是指redis在某个时间大量失效,突然造成数据库访问压力急剧增大,像雪崩一样,redis雪崩危害巨大,甚至有可能服务器宕机,给公司造成巨大的经济损失,下面我们就来说一说关于什么情况引起redis缓存穿透?我们一起去了解并探讨一下这个问题吧!
什么情况引起redis缓存穿透
一:redis雪崩
redis雪崩是指redis在某个时间大量失效,突然造成数据库访问压力急剧增大,像雪崩一样,redis雪崩危害巨大,甚至有可能服务器宕机,给公司造成巨大的经济损失。
解决方案:设置超时时间的时候要设置随机值,不要设置固定值
* 缓存雪崩: key在同一时间失效,导致大量请求去访问数据库
* 返回min 和max 之间的一个随机秒数
private Long getRandomExpirationTime(Integer min, Integer max) {
return RandomUtils.nextLong(min * 60 * 60, max * 60 * 60);
}
二: redis缓存穿透
缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求。由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。
在流量大时,可能DB就挂掉了,要是有人利用不存在的key频繁攻击我们的应用,这就是漏洞。
如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。
解决方案:
1.设置并发锁,防止请求大量请求数据库,如果获取到锁了,去数据库查询,如果没有,说明有其他线程在查询数据库,那么只需要重试一下就好了
public String get(key) {
String value = redis.get(key);
if (value == null) { //代表缓存值过期
//设置3min的超时,防止del操作失败的时候,下次缓存过期一直不能load db
if (redis.setnx(key_mutex, 1, 3 * 60) == 1) { //代表设置成功
value = db.get(key);
redis.set(key, value, expire_secs);
redis.del(key_mutex);
} else { //这个时候代表同时候的其他线程已经load db并回设到缓存了,这时候重试获取缓存值即可
Thread.sleep(50);
get(key); //重试
}
} else {
return value;
}
}
2.设置拦截器,对于不存在得key,进行拦截
三:缓存击穿
缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。
解决方案:
1.设置热点数据永不过期
2.加互斥锁
,免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com