redis缓存穿透、雪崩、击穿,以及解决办法

redis缓存穿透、雪崩、击穿,以及解决办法

我们先来讨论一个redis的使用场景:
使用redis作为缓存的时候,大部分做法是 先在redis里查询是否有该KEY, 比如查询用户信息时,先在redis里根据用户ID查询,如果没有则到数据库里查询, 如果在数据库里查询到了再放入redis,并设置过期时间,然后返回用户数据。

那么恭喜你,这种使用场景会导致以下3个问题
1、穿透:指的是redis中不存在该key, 而去查询数据库, 查到后再保存到redis, 查不到则直接返回。
这种情况看上去没毛病,正常业务操作也不会有啥问题。但是一些恶意攻击者可以使用大量不存在的key来攻击你的服务,当大量不存在的key来请求你的服务时,数据库接受大量的查询,达到一定的限度,将会压垮数据库,造成其他服务不可用。

2、雪崩:redis中大量的KEY同时过期,造成数据库瞬间压力增大,甚至压垮数据库。
造成雪崩有两种情况: a、大量缓存设置的过期时间一致,并且也是同时初始化到缓存里的,那么同时过期也是理所当然的。 b、redis某个节点宕机,造成该节点所有key过期。

3、击穿:当某个热点KEY存在时(比如秒杀活动等),该KEY过期的瞬间,大量的并发查询会落到数据库,给数据库造成压力。

解决方案:
1、穿透, 3种思路。 a、如果数据库根据该KEY未查到数据,不立即返回,先缓存一个空值,并且过期时间设置小一点,这样使用同一个KEY来恶意攻击就会失效。 b、恶意攻击者可能使用不同的不存在的KEY来攻击,这个时候可以用过滤器来过滤掉一部分无效KEY。 c、参考其他解决方案。

2、雪崩:针对雪崩产生的原因a, 我们在设置过期时间的时候可以加上一个随机因子,使key过期时间分散,不同类型的KEY设置过期时间不一样。 针对b,需要做高可用,冗余存储。

3、击穿:2种解决方案。a、使用排他锁,这样保证只有一个查询能到达数据库。b、热点key设置成永不过期。

其他解决方案:
产生以上3个问题共同特点是给数据库造成压力,如果不查询数据库,以上3个问题就不存在了。具体做法就是使用异步程序同步缓存。

你可能感兴趣的:(杂谈)