缓存穿透,缓存击穿,缓存雪崩
缓存穿透,缓存击穿,缓存雪崩
1、什么是缓存穿透
缓存穿透是指查询一个一定不存在的数据,一般情况下,首先查询缓存,如果缓存不存在,则去查询数据库,并把结果写入缓存,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。在流量大时,可能DB就挂掉了,要是有人利用不存在的key频繁攻击我们的应用,这就是漏洞。
2、如何解决缓存穿透
方案一
采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力
方案二
如果一个查询返回的数据为空【不论是真的数据为空还是因为系统故障】,仍然对这个空结果进行缓存,但是他的过期时间很短,最长不超过5分钟
3、什么是缓存击穿
对于设置了过期时间的缓存,如果这些缓存需要被高并发访问,那么就需要考虑一个问题,缓存击穿,就是当这个缓存将要到过期时间的时候,仍然存在大量的并发访问这个缓存,那么就会导致大量的请求压力被转移到数据库,因为缓存过期后,需要从数据库重新读取数据并写入缓存
4、缓存击穿与缓存雪崩的区别
缓存击穿针对的是某一个设置了过期时间的缓存,缓存雪崩针对的是很多设置了过期时间的缓存
5、如何解决缓存击穿
方案一
使用互斥锁[mutex key],业界比较常用的做法,是使用mutex。简单地来说,就是在缓存失效的时候(判断拿出来的值为空),不是立即去load db,而是先使用缓存工具的某些带成功操作返回值的操作(比如Redis的SETNX或者Memcache的ADD)去set一个mutex key,当操作返回成功时,再进行load db的操作并回设缓存;否则,就重试整个get缓存的方法。
- SETNX,是「SET if Not eXists」的缩写,也就是只有不存在的时候才设置,可以利用它来实现锁的效果。在redis2.6.1之前版本未实现setnx的过期时间。
方案二
提前使用互斥锁,在缓存内部设置一个过期时间A,但是A的值比实际的缓存过期时间B小,比如20秒,当从缓存读取到过期时间A已经过期的时候,马上延长过期时间A,并去数据库重新读取数据设置到缓存
方案三
在redis层面,设置这个缓存永不过期,这样就不会出现热点缓存存在过期的问题,但是在缓存的值内部设置一个过期时间,发现这个缓存过期的时候,就通过异步线程去更新缓存
方案四
采用netflix的hystrix,可以做资源的隔离保护主线程池,如果把这个应用到缓存的构建也未尝不可。
6、什么是缓存雪崩
缓存雪崩是我们的缓存设置了相同的过期时间,在到达这个时间截点的时候,缓存全部失效或者大量缓存失效,导致数据库瞬间要承受极大的查询压力崩溃,如果数据库抗住了压力,也会因为大量的缓存写入导致缓存服务宕机
7、如何避免缓存雪崩
我们可以在原有的缓存过期时间上增加一个随机值,让缓存过期能够尽量均匀分布
文章来源: wretchant.blog.csdn.net,作者:简简单单OnlineZuozuo,版权归原作者所有,如需转载,请联系作者。
原文链接:wretchant.blog.csdn.net/article/details/88024498
- 点赞
- 收藏
- 关注作者
评论(0)