缓存穿透
当客户端频繁地向服务器请求一个缓存中不存在的数据时,服务器会不断查询数据库,数据库可能会因此挂掉。
解决方案
这里有一个简单粗暴的方法。
当查询数据库时,如果结果返回null,这时仍然对其结果进行缓存,但缓存的过期时间很短。
缓存雪崩
在设置缓存时都设置了相同的过期时间,致使缓存同时失效,所有请求将全部转发给数据库,数据库瞬时压力过重,导致雪崩。
解决方案
可以在原有的失效时间基础上增加一个随机值,使得每个key的过期时间分散开,不会集中在同一时间段失效。
缓存击穿
一个存在的key,在缓存过期的那一刻,刚好有大量的请求,大并发的请求会击穿到DB,造成瞬时DB请求量大,压力骤增。
这里的缓存击穿和缓存雪崩看似相同,实际上有一点区别。
* 击穿是针对的某一个key
- 雪崩是有很多的 key 同时失效
解决方案
在访问key之前,可以采用SETNX(set if not exists)来设置另一个短期的key,通过其来锁住当前key的访问,访问结束就删除该短期key。
``` 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并回设到缓存了,这时候重试获取缓存值即可
sleep(50);
get(key); //重试
}
} else {
return value;
}
}
</senction>
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于