缓存雪崩、缓存穿透、缓存预热、缓存倾斜、缓存穿刺击穿、缓存更新、缓存降级 等
程序员文章站
2022-06-19 11:30:06
...
缓存雪崩、缓存穿透、缓存预热、缓存倾斜、缓存穿刺/击穿、缓存更新、缓存降级 等
一、缓存雪崩
由于原有的缓存集体性的在同一时间段内过期失效,而新缓存未到期间,所有原本应该访问缓存的请求都去查询数据库了,这会对数据库造成巨大压力,会导致数据库崩掉。
从而形成一系列连锁反应(雪崩),一直造成整个系统崩溃!
缓存正常从Redis中获取,示意图如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-io1YIwTV-1578409259895)(mdpic/20180312200437182)]
缓存集体性的失效瞬间,示意图如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YgZDeecV-1578409259898)(mdpic/20180312200640916)]
解决办法:
缓存失效时的雪崩效应对底层系统的冲击非常可怕!
方案一:
大多数系统设计者考虑:用加锁或者队列的方式,来保证同一时间内不会有大量的线程,同时对数据库进行读写,从而避免 数据库崩溃掉。
方案二:
还有一个简单方案就是:将缓存的失效时间分散开,这样每一个缓存的过期时间的重复率就会降低,就很难引发大量的缓存集体性失效的事件。
二,缓存穿透
缓存穿透是指:数据库没有这个数据,缓存中也没有。这样就导致每个用户每次在查询的时候,在缓存中找不到,都要去数据库中再查一遍。
这样每次查询都需要到数据库,无故的剧增了数据库的压力,数据库表示很难受。
解决办法:
方案一:
采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对数据库的查询压力。
方案二:(简单粗暴)
如果一个查询返回的数据为空,我们仍然把这个空结果进行缓存,这样用户请求第二次到缓冲中获取就有值了,而不会继续访问数据库,这种办法最简单粗暴!
三,缓存击穿/穿刺
数据库中有该数据,缓存中也有,但在处理大量请求的时候、缓存突然过期了,此时这些大量请求会到达数据库,造成数据库瞬间压力骤增、甚至崩溃掉。
解决方案:
方案一,设置这个热点数据永不过期;
方案二,在请求访问key之前,采用SETNX来设置一个短期key,锁住当前key的访问,访问结束再删除该短期key。
方案三,给数据库加互斥锁。
缓存中没有数据,那么想要访问数据库的多个线程,需要先获取到锁才能从数据库中去取数据,第一个线程没释放锁之前,其他的线程都得在外边等待。
然后第一个线程从数据库中取了一次数据之后,顺手更新一下缓存,于是其他的线程再次去缓存中请求数据就行了。
三,缓存预热
缓存预热就是系统上线之后,将一些缓存数据先加载到缓存系统中。这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!
用户直接查询事先被预热好的缓存数据!
四,缓存更新
除了缓存服务器自带的缓存失效策略之外,我们还可以根据具体的业务需求,进行自定义的缓存淘汰,常见的策略有两种:
(1)定时去清理过期的缓存;
(2)当有用户请求过来时,先判断这个请求所用到的缓存是否过期,过期的话就去数据库中得到新数据,同时并更新到缓存中。
五,缓存降级/服务降级
当访问量剧增、服务出现问题时,仍然需要保证核心的服务还是可用的,这时可以采用关闭一些非核心的服务的方式,来保证核心服务可用。即,丢卒保帅。
降级的最终目的是保证核心服务可用。
六,缓存倾斜
缓存倾斜又称为:热点key倾斜。
即,缓存中存在这个key,但是由于这个key突然成为高热点key,比如明星出轨,这样导致大量的用户突然高并发的访问这个高热点key所在的那台缓存服务器,最终导致那台缓存服务器崩掉,继而请求又到达下一个缓存服务器,下一个缓存服务器又承受不住而崩掉,最终导致整个缓存模块崩掉。(是缓存崩掉了,跟数据库关系不大)
解决办法:
方案一:
将一些特别热点的key直接放在客户端进行存储,设置过期时间,过期后再从后台中查询。
方案二:
我们可以将这个热点key复制出多个子key,每个子key的value值一样,查询的时候使用hash取模算法,将压力分摊到不同的节点。
将一些特别热点的key直接放在客户端进行存储,设置过期时间,过期后再从后台中查询。
方案二:
我们可以将这个热点key复制出多个子key,每个子key的value值一样,查询的时候使用hash取模算法,将压力分摊到不同的节点。
上一篇: spring security
下一篇: spring security