方案

缓存雪崩、缓存穿透和缓存击穿

2021-07-05  本文已影响0人  小丸子的呆地

缓存雪崩

指的短时间内,大量缓存数据过期逐出,还没有从新加载到缓存中时,流量全部打到数据库上,导致数据库负载飙升,导致数据库压力过大甚至被压垮的场景。

我们使用缓存的目的,一是提升接口查询性能,二是降低数据库压力。
很明显,在缓存雪崩场景下这二者不但没有解决,反而成了服务最致命问题。

解决办法

造成数据库负载飙升的主要原因,是缓存失效,对同一数据的多次访问全部请求到了数据库上,那么这时候一旦从缓存中拿不到数据,就对此行数据加锁,保证同时只有一个请求访问数据库,而后将数据再加载到缓存。这样相同的请求也不会对数据库造成多次访问。
但是,服务中,任何加锁的方法,都应当只能是最终的方案,任何加锁的解决办法都不是一个好的办法。因为加锁,将请求同步处理,导致服务的性能下降;并且加锁也是一个十分消耗资源的事。

缓存数据的过期时间,不要都设置在同一时间节点上,否则在这个时间节点,会有海量数据过期逐出。过期时间的设置应当尽量平滑。

设置热点数据永不过期,这些热点数据可能会占到所有请求流量的绝大部分。
设置热点数据在分布式缓存中分布尽量均匀。

设置多重缓存,缓存降级。

缓存穿透

指的是查询的数据数据库中不存在,也就不会加载到缓存中,导致每次查询都会请求到数据库。

利用布隆过滤的特性,将不为空的数据放到过滤器中,过滤出一定不存在的记录,这类数据就直接返回空值。
有局限性,比如有些数据可以在为空和不为空之间切换,而布隆过滤器无法剔除数据。

可以对空值进行缓存。

使用其他标记位,标记此行记录是否存在。

缓存击穿

指的是热点数据在更新数据、刷新缓存或者缓存过期的一瞬间犹豫缓存失效,导致海量流量请求到数据库。

一旦从缓存中拿不到数据,就对此行数据加锁,保证同时只有一个请求访问数据库,而后将数据再加载到缓存。这样相同的请求也不会对数据库造成多次访问。

使用copyOnWrite思想,当新缓存完全准备好再提供查询,在这期间都返回老数据。

上一篇下一篇

猜你喜欢

热点阅读