原来解决Redis击穿、雪崩、穿透真的不是那么简单的一件事!!(缓存雪崩)

目录

 

一、缓存雪崩

二、解决方案分析

三、总结


一、缓存雪崩

                                          原来解决Redis击穿、雪崩、穿透真的不是那么简单的一件事!!(缓存雪崩)

上一篇文章主要分析了缓存的实际应用场景,项目请求流程,缓存问题的出现场景,本文主要解析缓存雪崩。

首先,再了解了缓存击穿后,再了解缓存雪崩,大家可能更容易理解。简单点说,就是大面积的缓存key失效,导致大量请求绕过缓存直接访问数据库,导致数据库一时间压力过大,处理能力下降,甚至崩溃。

其实,这样一读起来大家可能能感觉出来,所谓缓存击穿,是一个热点key失效,导致一个请求的上万并发直接打到数据库导致数据库崩溃。但是雪崩失效的可能并不是热点key,也就是几百或者几十的并发,但是大面积的key失效,这样所下来,数量也是很客观的。这样一来,我们可以给缓存雪崩拆分开其实就是一个个缓存击穿的集合,这样理解起来也方便些。

解决缓存雪崩网上有也有很多解决方案,博客也有很多,总结起来一方面是key的失效方案,另一方面是监听。

二、解决方案分析

  • 分散缓存key的失效时间

这个方案是最常规,也是普遍被大家认可的一种方案,分散key的失效时间,最简单的就是设置失效时间按照实际业务和规律设置,比如根据key的热点程度,key的更新频率,热点的设置的短一些,更新频率不是很大的设置的长一些,这样错峰设置,即使同一时间失效的也不会是大面积的,跟我们做抢单业务,流量削峰一样,让压力分散开,每一个时间段数据库的压力都不会很大。

但是这样有一个问题,就是数据一致性的问题,如果我们对数据一致性要求不是很高,也就是说即使缓存没有更新及时,查询展示的还是旧数据也没有什么关系。但是如果很高怎么办?key必须再某一时间段同时失效更新?这样某一刻肯定缓存中key是丢失的状态,那该怎么去解决呢?

  • 设置缓存key的失效标识key

这个的意思就是在缓存key前再加一道防护,简单的来说就是在加一个失效标识key,判断我这个key到底有没有失效,如果这个key不在了,我再去查数据库,顺便放到缓存中。如果标识key存在那么证明没有失效,直接返回缓存中的数据即可。设置个定时任务,某个时间定时刷新缓存和标识。

但这还是有些问题,比如这个标识key准确性的问题,比如,标识key标识的确没有失效。但是缓存key丢失了,那我们查询key的数据不就不存在了么?还有标识key和缓存key的失效时间设置,如何保证一致性?

所以我本身是感觉这个方案不是很友好。

  • 接口设置随机延迟时间,缓解压力

这个是解决数据强一直性问题,比如某个时间段必须同时刷新最新的缓存,我们可以在查询的业务中加入几毫秒的随机延迟时间,这样部分请求在查询数据库后会给数据放回缓存,后面的延迟请求从缓存中也可以取到数据,当然几毫秒的延迟用户体验也不会有什么影响。当然,你也别直接设置几秒的延迟,那肯定是不行的,这个延迟时间还是要结合实际业务和查询效率具体蛇者的。

  • 设置二级缓存

这相当于在数据库前设置两个保镖,当Redis大面积数据失效以后,打过来的请求会访问二级缓存,如果二级缓存没有才会真的查询数据库。常用的二级缓存有MangoDB。

但是还要注意的一点就是一级二级缓存的数据一致性问题。

三、总结

其实解决方法有很多种,但是具体使用哪种还要结合实际业务具体分析。当然如果数据强一致性的问题,我建议还是能避免使用缓存就避免,当然如果数据量过大,数据库确实吃不消,可以考虑使用es。