参考来源:
关于【缓存穿透、缓存击穿、缓存雪崩、热点数据失效】问题的解决方案
定义 | 问题 | 解决方案 | |
---|---|---|---|
缓存穿透 | 业务系统访问缓存和数据库都查询不到的数据。
发生情况: 1.恶意攻击,故意营造大量不存在的数据请求 2.代码逻辑错误 | 请求都会落到数据库中,数据库压力剧增 | 1.缓存空值 将数据库查询结果为空的key也存储在缓存中 场景:空数据的key数量有限、key重复请求概率较高
BloomFilter存储目前数据库中存在的所有key 当业务系统有查询请求的时候,首先去BloomFilter中查询该key是否存在。若不存在,直接返回null。若存在,则继续执行后续的流程。 场景:空数据的key各不相同、key重复请求概率低 |
缓存击穿 | 大量的请求同时查询一个 key 时,此时这个key正好失效了,就会导致大量的请求都打到数据库上面去。 | 造成某一时刻数据库请求量过大,压力剧增 | 将热点数据设置为永远不过期;或者基于 redis or zookeeper 实现互斥锁,等待第一个请求构建完缓存之后,再释放锁,进而其它请求才能通过该 key 访问数据。 |
缓存雪崩 | 某一时刻发生大规模的缓存失效的情况 例:缓存服务宕机 | 大量的请求进来直接打到DB上面,DB直接挂掉 | 1.事前
2.事中
3.事后
|
热点key | 缓存会设定一个失效时间,但一些请求量极高的热点数据而言,一旦过了有效时间,此刻将会有大量请求落在数据库上 | 可能会导致数据库崩溃 | 1.互斥锁 在第一个请求去查询数据库的时候对他加一个互斥锁,其余的查询请求都会被阻塞住,直到锁被释放,从而保护数据库。 但是也是由于它会阻塞其他的线程,此时系统吞吐量会下降。需要结合实际的业务去考虑是否要这么做。
2.设置不同的失效时间 在设置缓存过期时间的时候,让失效的时间错开。如:在一个基础时间上加/减一个随机数 |