谈谈缓存击穿、缓存穿透、缓存雪崩

缓存击穿

缓存击穿是指一个请求要访问的数据,缓存中没有但是数据库中有 (这个可以强调一下,跟缓存穿透区分开,后者是缓存、数据库中皆没有) 的情况。

缓存击穿一般都是缓存过期所致。

如果这是一个热点key,某一时刻并发访问该缓存的用户特别多。这么多用户请求同时过来,在缓存里面取不到数据,都同时去访问数据库读取数据,给数据库造成很大的压力,甚至会崩溃。

一个数据有缓存,每次请求都从缓存中快速地返回了数据。但是某个时间点缓存失效了,某个请求在缓存中没有拿到数据,转而去数据库获取数据,这时候我们就说请求"击穿"了缓存。

解决方案

1.只放行一个请求到数据库,然后做构建缓存的操作。

怎么做到多个请求只放行一个?可以借助Redis的setnx命令设置一个标志位。设置成功的就放行,设置失败的就轮询等待。

2.后台续命

该方案的思想是后台开一个定时任务,专门用于主动更新即将过期的数据。

比如程序中设置hotkey这个热点key的时候,设置了过期时间为10分钟;后台程序在第8/9分钟的时候,去数据库查询数据并重新放到缓存中,同时再次设置缓存的过期时间为10分钟。

3.永不过期

缓存被击穿的原因是设置了超时时间,在超时时刻来临时,数据被清理。那么,不设置超时时间是不是就能解决该问题了?

如果结合业务场景能够确定某个key一定是热点key,会不断有大量请求来访问该数据,且该key对应的value在较长的时间内不会发生变化,这样的数据,可以考虑不设置过期时间。

缓存穿透

缓存穿透是指一个请求要访问的数据,缓存和数据库中都没有,而用户短时间、高密度地发起这样的请求,每次都打到数据库服务上,给数据库造成了压力。

一般来说这样的请求属于恶意请求。举个例子,你明知【why技术】公众号是一个技术公众号,而你却硬要去它那里买啤酒买花生,这不是为难它吗?这就是所谓的恶意请求。

解决方案

缓存空对象

即使在数据库没有查询到数据,也把这次请求当作key缓存起来,value可以是NULL。

下次同样的请求就会命中这个缓存数据返回NULL,缓存层就处理了该请求,不会对数据库产生压力。实现简单,开发成本低。

但随之而来的一个面试题:

"对于恶意攻击,请求的时候key往往各不相同,且只请求一次,那你要把这些 key 都缓存起来的话,因为每个 key 都只请求一次,那还是每次都会请求数据库,没有保护到数据库呀?"

布隆过滤器,了解一下?

布隆过滤器的特性是说某个值存在时,这个值可能不存在。当它说不存在时,那就肯定不存在。可以基于这个特性,已有数据都构建到布隆过滤器里面去,然后它可以帮忙挡住绝大部分的攻击。(已有的数据都构建在布隆过滤器中了,布隆过滤器说没有的,就一定没有(比如恶意请求的数据),因此可以挡住绝大部分的攻击)

布隆过滤器的延伸:https://mp.weixin.qq.com/s/8jheJ8abNDeZSExYMZRsGg

布隆过滤器的缺点:

1.不支持删除。本来布隆过滤器就是用在大数据量的场景下,随着时间的流逝,过滤器的数组中为 1 的位置越来越多,带来的结果就是误判率的提升。从而必须进行重建。

2.查询性能不高。因为真实场景中过滤器中的数组是非常长的,经过多个不同 Hash 函数后,得到的数组下标在内存中的跨度可能会非常的大。跨度大,就是不连续。不连续,就会导致 CPU 缓存行命中率低。

更好的解决方案:布谷鸟过滤器。

区分"缓存击穿"与"缓存穿透"

一个是"穿",一个是"透"。

穿,仅穿过缓存打到数据库。

透,不仅穿过了缓存,还穿过了数据库,"透",直接干到底。

缓存雪崩

缓存雪崩是指缓存中大多数的数据在同一时间到达过期时间,而查询数据量巨大,这时候,又是缓存中没有,数据库中有的情况了。

和前面讲的缓存击穿不同的是,缓存击穿指大量的请求并发查询同一条数据。缓存雪崩是不同数据都到了过期时间,导致这些数据在缓存中都查询不到。

解决方案

错峰过期

在设置 key 过期时间的时候,再加上一个短的随机过期时间,这样就能避免大量缓存在同一时间过期,引起缓存雪崩。

题外话:Redis挂了怎么恢复

服务挂了怎么恢复?自然是重启

但是重启之前有个小细节:把流量摘掉可以先把流量拦截在入口的地方,比如简单粗暴地通过 Nginx 的配置把请求都转到一个精心设计的错误页面。

这样做的目的是为了防止流量过大,直接把新启动的服务,启动一个打挂一个的情况出现。

要是启动起来又扛不住了,请在心里默念分布式系统三大利器:缓存、拆分、加钱(加机器)。

不行就加钱,堆机器嘛。

要觉得堆机器没啥技术含量,你就再从缓存预热的角度答一个。

就是当 Redis 服务重新启动后,通过程序先放点已知的热点 key 进去,系统再对外提供服务,防止缓存击穿的场景。

参考资料

https://www.cnblogs.com/thisiswhy/p/15089432.html

posted @ 2021-08-28 14:27  chan_xm  阅读(475)  评论(0)    收藏  举报