本篇我们继续来讨论缓存的另一个问题——缓存雪崩。
缓存雪崩
什么是缓存雪崩?
其实把缓存击穿搞清楚了,那么理解缓存雪崩就容易得多了。
缓存击穿是指1个热key失效
,而缓存雪崩,顾名思义,指的就是大面积的key在同一瞬间全部失效
,导致大量的请求打到数据库上,就像雪崩一样,从而造成数据库响应不及时挂掉。这种属于自然雪崩,主要是引起周期性的压力波峰,还有另一种非自然雪崩,就是缓存服务某个节点或多个节点甚至全部节点都突然宕机,导致所有的请求都打到数据库上,进而导致数据库宕机,这种也是不可预知的雪崩。
所以,对于缓存雪崩来说,一般少量的缓存失效,所带来的数据库并发压力是不会太大的,而是大量的缓存同时失效,导致所有key的并发加起来打到数据库上,才会影响到我们的数据库。
其实,在真实场景中,缓存雪崩是一个更容易发生的问题,因为它不像缓存击穿那么极端,1个key就有成千上万的并发量,直接把数据库击垮,而是一个key可能只有几十几百的并发量,然后大量的key同时过期,导致很多key的并发叠加起来,积累到成千上万,再把数据库击垮。
如何解决?
我们既然知道了缓存雪崩产生的原因,那么自然而然就能见招拆招,找到对应的解决方案。
因为缓存雪崩是大面积的key同时过期失效,才导致大量的并发直接打到数据库上,那么我们很正常的思路就是让并发分散开来
。
第一种常见的做法是分散缓存数据的过期时间,防止同一时间大量数据过期现象发生
。
我们可以通过随机初始化过期时间,使得key的过期时间分散开来,一个一个过期,并发量也就被分成一部分一部分,这样一来每次打到数据库上的只有少量请求。看起来就像是削峰操作,这种做法是最简单有效的,因此绝大多数情况下也是采用这种方法。
但是,如果你的业务对时间点的要求很高,比如:必须在每天的指定时间去更新数据。
由于业务需求,必须在固定的时间点刷新数据,并且不允许出现旧数据,也就是说必须让缓存数据在同一时刻全部失效。那么,像这样的业务我们又该如何解决呢?
因为这个场景非常类似削峰操作,所以自然而然联想到消息队列,也就是先把请求打到MQ上,然后再一个一个依次消费。
这种做法合理吗?从系统实现的角度来看,这样确实可以保证数据库的请求压力被扛下来,再进行异步消费。对于写操作,使用异步写是没有任何问题的,因为用户只要求把数据存入而已,但是对于读操作,是不应该使用到消息队列的,因为这样会影响用户接收到消息的时间,使用队列依次读取,那么大量用户的响应延迟就会变高,对于用户体验来说是不友好的。所以对于读请求,不适合使用队列的方式,因为它把请求串行化了,不再是并发执行。
既然这种做法不合理,那么还有其他的方法吗?这时,就有人提出让缓存提前更新的观点,也就是预加载缓存,提前主动加载热门数据到缓存中,在数据过期之前进行刷新,减少雪崩的风险。
但是提前更新可能会导致数据不准确,例如在23:58开始更新,然后在23:59的时候又有大量的数据被修改,用户在24:00查看数据时发现数据仍然没有变化,他们就会认为24:00系统更新数据的说法不靠谱。
因此Redis缓存还是必须要同一时间点失效,不能把时间分散开来。既然Redis的过期时间不能分散,不能在Redis上做文章,那么我们不妨改变一下思维方式,是谁来访问Redis,是service服务层,我们可以把service服务层的查询请求分散开来,利用客户端设置一个短暂的随机延迟时间,使得查询请求分散开,少量的请求先查询,就会读数据库,存入Redis缓存,其他请求由于随机时间,稍微慢一点再去Redis读数据。
也就是从业务层把时间分散开来,这样做所带来影响就是用户等待时会多几十毫秒的延迟,但是对于用户感知来说是微乎其微的,可以忽略。
对于缓存雪崩还有一些其他的解决方案,例如:
-
Redis一般都是集群部署,可以把这些热点的key放到不同的节点上,让这些热点的缓存平均分布在不同的Redis节点上。
-
使用多级缓存架构,引入多级缓存,如本地缓存、分布式缓存和集中式缓存,这样即使某个层级的缓存出现问题,仍然可以从其他层级获取数据。
-
限流和熔断,对于缓存失效是的瞬间高并发请求,可以实时限流和熔断机制,控制系统的负载均衡,防止系统崩溃。
-
数据库容灾和优化,确保数据库具备高可用性,采取备份策略的故障转移方案,同时对数据库进行性能优化。
-
监控和报警,建立监控系统,实时监测缓存的状态和命中率,并设置合适的报警机制,及时发现并处理潜在的缓存问题。
总之,缓存雪崩最佳的解决方案其实就是要结合实际工作和业务场景,选择一种或多种方法搭配使用。
关于缓存穿透以及解决方案,例如布隆过滤器,由于篇幅关系,我们放在下一期探讨。
未完待续……
脚踏实地,仰望星空,和小编一起学习软件测试,升职加薪!
总结:
感谢每一个认真阅读我文章的人!!!
作为一位过来人也是希望大家少走一些弯路,如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些自动化测试的学习资源,希望能给你前进的路上带来帮助。
软件测试面试文档
我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
视频文档获取方式:
这份文档和视频资料,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!以上均可以分享,点下方小卡片即可自行领取。