的缓存异常处理,缓存雪崩

缓存雪崩:缓存雪崩我们可以简单的理解为:由于原有缓存失效,新缓存未到期间(例如:我们设置缓存时采用了相同的过期时间,在同一时刻出现大面积的缓存过期),所有原本应该访问缓存的请求都去查询数据库了,而对数据库CPU和内存造成巨大压力,严重的会造成数据库宕机 。
如何解决微服务架构中的雪崩问题?

的缓存异常处理,缓存雪崩


在分布式系统都存在这样一个问题,由于网络的不稳定性,任何一个服务的可用性都无法做到100%。当网络不稳定时,作为服务的提供者,自身可能会被拖死,导致服务调用者阻塞,最终可能引发雪崩效应 。1 雪崩问题的本质我们先来看一个分布式系统中常见的简化模型 。Web服务器中的容器启动时后台初始化一个调度线程,这个线程主要负责处理Http请求,调度线程从线程池中取出一个工作者线程来处理该请求,从而实现并发控制的目的 。
Servlet Container是我们的容器,如Tomcat、Netty等 。一个用户请求有可能依赖其它多个外部服务 。考虑到应用容器的线程数基本都是固定的(比如Tomcat的线程池默认200),那么在高并发场景下,如果某一个依赖的外部服务超时阻塞,就有可能使得整个主线程池打满,增加内存消耗 。更进一步,如果线程池被占满,那么整个服务将不可用,继而会重复产生上述问题 。
整个系统就像雪崩一样,最终崩掉 。2 雪崩效应产生的几种场景流量激增:比如异常流量、用户重试导致系统负载升高;缓存刷新:假设A为客户端,B为服务器端,我们假设A的请求都流向B,如果请求超出了B的负载,就会造成B系统崩溃;程序有Bug:代码循环调用的逻辑问题,资源未释放引起的内存泄漏等问题;硬件故障:比如宕机,机房断电,光纤被挖断等;线程同步等待:系统间经常采用同步服务调用模式,核心服务和非核心服务共用一个线程池和消息队列 。
【的缓存异常处理,缓存雪崩】如果一个核心业务线程调用非核心线程,这个非核心线程交由第三方系统完成,当第三方系统本身出现问题,导致核心线程阻塞,一直处于等待状态,而进程间的调用是有超时限制的,最终这条线程将断掉,也可能引发雪崩 。3 雪崩效应的常见解决方案针对上述雪崩情景,有很多对应的解决方案,但没有一个万能的模式能够应对所有场景 。
什么是缓存击穿,它和缓存雪崩有什么区别么?
的缓存异常处理,缓存雪崩


缓存击穿和缓存雪崩的区别在于:雪崩针对很多 key,而击穿只针对于某一个热点 key 。缓存雪崩的实现方案有不少,有一些能够解决缓存击穿,有一些却不能,例如:设置缓存永不过期,这个方法虽然很暴力,但是确实能解决大部分的问题,当然,大部分场景也不太适用;设置随机过期时间,这个方案对于缓存击穿来说就不太适用了,因为击穿只针对一个热点 key,只要它一失效,大量的访问就会击垮数据库;其余的方案比如使用互斥锁、双缓存机制,也都可以解决缓存击穿的问题,让我们看看这些方案的具体实现 。
主动刷新缓存缓存设置成永不过期,在更新或删除 DB 中的数据时,也主动地把缓存中的数据更新或删除掉 。这个方案很容易理解,但是实现起来却很复杂,但凡需要使用缓存的数据,都需要增加双写数据库和缓存的代码,并且双写过程中,还需要保持数据一致性 。检查更新缓存依然保持设置过期时间,每次 get 缓存的时候,都和数据的过期时间和当前时间进行一下对比,当间隔时间小于一个阈值的时候,主动更新缓存 。

推荐阅读