缓存穿透,缓存击穿,缓存雪崩

本文深入探讨了缓存穿透、缓存击穿和缓存雪崩这三个常见的缓存问题,详细解释了它们的发生原因及对系统的影响,并提出了多种有效的解决方案,包括使用布隆过滤器、互斥锁、设置随机过期时间等,帮助读者全面理解并应对缓存挑战。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

缓存穿透,缓存击穿,缓存雪崩


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、如何避免缓存雪崩

我们可以在原有的缓存过期时间上增加一个随机值,让缓存过期能够尽量均匀分布

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

简简单单OnlineZuozuo

感谢哥哥姐姐的打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值