如何解决缓存雪崩、击穿、穿透

缓存雪崩

缓存雪崩是指大量的应用请求无法在 Redis 缓存中获取数据。紧接着,应用将大量请求发送到数据库层,导致数据库层的压力激增。

大量Key过期

在某一个时间点大量缓存过期。导致所有的请求被发往数据库,这种情况可以在设置过期时间的时候可以使用一个偏移量来对过期时间进行重新计算,避免同一时间过期。

如果已经发生雪崩,可以使用服务降级来应对,当业务应用访问的是非核心数据时直接暂停从缓存中查询数据,直接返回预定义的信息或者空值和错误信息。

当访问核心数据的时候依旧可以查询缓存和数据库。这样一来,只有部分过期数据的请求会发送到数据库,数据库的压力就没有那么大了

Redis实例宕机

Redis 缓存实例发生故障宕机了,无法处理请求,这就会导致大量请求一下子积压到数据库层,从而发生缓存雪崩,甚至是整个系统的崩溃。

这种情况可以使用熔断机制,当一段时间间隔内,多次发生访问redis失败,就进入熔断状态。一段时间之后允许少量请求通过,如果请求都执行成功,则退出熔断状态,如果请求仍旧失败,在下一个时间段,再次允许少量请求通过,试探服务是否恢复。

或者使用限流机制来应对,通过限制访问量来保证数据层不会雪崩。

缓存击穿

缓存击穿是指,针对某个访问非常频繁的热点数据的请求,无法在缓存中进行处理,紧接着,访问该数据的大量请求,一下子都发送到了后端数据库,导致了数据库压力激增,会影响数据库处理其他请求。缓存击穿的情况,经常发生在热点数据过期失效时。

为了避免缓存击穿给数据库带来的激增压力,解决方法也比较直接,对于访问特别频繁的热点数据,就不设置过期时间了。这样一来,对热点数据的访问请求,都可以在缓存中进行处理,而 Redis 数万级别的高吞吐量可以很好地应对大量的并发请求访问。

或者主动给某些热点的数据做过期时间延期操作。保证热点数据时效性。

缓存穿透

缓存穿透是指要访问的数据既不在 Redis 缓存中,也不在数据库中,导致请求在访问缓存时,发生缓存缺失,再去访问数据库时,发现数据库中也没有要访问的数据。形成了一个死循环,缓存穿透一般发生在业务层的错误操作,删除了数据,或者是恶意攻击。

  1. 可以针对查询的数据在 Redis 中缓存一个空值或是和业务层协商确定的缺省值(例如,库存的缺省值可以设为 0)。紧接着,应用发送的后续请求再进行查询时,就可以直接从 Redis 中读取空值或缺省值,返回给业务应用了,避免了把大量请求发送给数据库处理,保持了数据库的正常运行。

  2. 或者使用布隆过滤器来判断数据是否存在。但是布隆过滤也不能保证某个数据一定存在,只能说这个数据可能存在。

  3. 请求入口的前端进行请求检测。缓存穿透的一个原因是有大量的恶意请求访问不存在的数据,所以,一个有效的应对方案是在请求入口前端,对业务系统接收到的请求进行合法性检测,把恶意的请求(例如请求参数不合理、请求参数是非法值、请求字段不存在)直接过滤掉,不让它们访问后端缓存和数据库。这样一来,也就不会出现缓存穿透问题了。

三者区别

缓存雪崩,缓存穿透本质上是 Redis 实例没有起到缓存层作用这种情况,在损失业务吞吐量的代价下,在时间的作用下,随着过期key慢慢填充,Redis实例可以自行恢复缓存层作用。

缓存穿透的场景,是因为用户要让 Redis和数据库提供一个它没有的东西。不论时间过去多久,都不会自然恢复,必须人工介入。


如何解决缓存雪崩、击穿、穿透
http://example.com/posts/53676.html
作者
她微笑的脸y
发布于
2022年8月1日
许可协议