跳到主要内容

缓存雪崩

刚开始key对应的数据存在,因为这些key都是同时写入的,并且设置的过期时间都一样, 那么在过期时间到的时候,会有大量的key一起过期,如果这个过期的时间节点有大量请求,需要找这些key所对应的数据, 但是这些请求发现缓存过期,就会查询数据库,查完后并回设到缓存, 这个时候大并发的请求可能会瞬间把后端数据库压垮。

缓存雪崩与缓存击穿的区别在于, 击穿是一个key的高频率访问过程中的过期问题。 雪崩是多个key的正常访问过程中,多个key同时过期的问题,其中雪崩的多个key也可能是高频率数据,也可能是普通数据。

最大的区别在于这里针对很多key缓存,缓存击穿是指的某一个key。

图解

缓存雪崩前的正常访问

雪崩前的正常访问

缓存过期后,造成雪崩现象,大量key访问数据库

雪崩后直接访问了大量key访问数据库

解决方案

架构增加多级缓存

比如增加nginx缓存,增加redis缓存,增加数据库第三方缓存,数据库第三方缓存比如Java中的ehcache中间件。

使用锁和队列

在并发不高的情况下,可以使用锁机制和队列机制,现在可以做到顺序执行缓存和数据库直接的交互逻辑。

从而保证了,在缓存时效的同一时刻,不会造成大量请求到数据库层面。

设置逻辑过期时间

在key的设置过程中,不设置过期时间,只在key的值内部加入一个过期时间的标识,其中这个过期标识要比真正的过期时间要提前一些时间,也就是逻辑过期时间, 在另外的线程,如果发现某些key满足了提前量过期时间的标识,那么就请求一下数据库,把数据库覆盖到key身上,同时修改新的具有时间提前量的过期时间标识。

缓存失效时间分散开

在批量设置一批key的时候,设置的过期时间在原有的时间上加上一个随机值,比如1-5分钟随机,这样每一个key缓存的过期时间都不相同,避免了同一时间大量缓存一起过期的问题,增加数据库压力。