Redis的穿透、击穿、雪崩问题

目录

Redis穿透

解决方法1:布隆过滤器

解决方法2:返回空对象

解决方法3:接口校验

Redis击穿

解决方案1:可以设置热点数据永远不过期

解决方案2:添加锁

Redis雪崩

解决方案1:加互斥锁

解决方案2:将key的过期时间随机化

解决方案3:使用Redis集群提高可用性

解决方案4:数据预热

补充:


因为Redis是在内存中操作的,速度很快,所以我们经常使用Redis缓存数据。但是东西总有两面性,Redis也有它的问题,就是穿透、击穿、雪崩问题,现在记录一下。

Redis穿透

定义:如果我们查询一个数据会先到缓存中查,如果没有才去数据库查。如果有人利用不存在的key一直访问就会一直到数据库中查,这样就会导致Redis缓存穿透掉直接到数据库。这样肯定是不好的。

Redis的穿透、击穿、雪崩问题_第1张图片

解决方法1:布隆过滤器

将所有可能存在数据,分别通过多个哈希函数生成多个哈希值,然后将这些哈希值存到一个足够大的bitmap中,此时一个一定不存在的数据就会被这个bitmap拦截直接return,从而减少了数据库的查询压力。

解决方法2:返回空对象

当某个请求的key在redis缓存和数据库中都查不到数据时,直接将这个key对应的空数据存在redis中,这样下次这个key又过来就直接走缓存,就不会到数据库中了,这个key和空数据应该设置过期时间,防止存储过多空数据浪费内存。

redisCache.getItem(key) = null & 数据库中也查不到

redisCache.setItem(key,null,2分钟,minute)

解决方法3:接口校验

在接口层,获取请求的参数进行校验,发现有不合法的key直接return掉,连查询都不给机会。

boolean isNormal = checkKey(key);
if(isNormal){
    return ...
}

Redis击穿

定义:某一个热点key在redis缓存中过期失效了,这时大量用户对这个热点数据进行请求,但是由于缓存中已经失效了,就会到数据库中查询,此时数据库一时处理大量的查询,又是同样的数据像在数据库上击穿了一个点。

Redis的穿透、击穿、雪崩问题_第2张图片

解决方案1:可以设置热点数据永远不过期

将那些用户经常查询的数据对应的key设置永远不过期,就可以保证走缓存了。

解决方案2:添加锁

可以使用分布式锁或互斥锁。多个请求都同时查询这个热点数据,使用锁机制只让第一个请求获取锁去数据库查这个热点数据,其他线程保持阻塞,这个热点数据查询出来后写入到redis缓存中,其他请求后面从缓存中取数据即可。

Redis雪崩

定义:和击穿不同的是,击穿是某条数据过期了。雪崩是大批量数据都过期了,而这大批量数据的请求过来后,Redis缓存失效,请求直接落到数据库上,引起数据库压力过大甚至宕机。

Redis的穿透、击穿、雪崩问题_第3张图片

解决方案1:加互斥锁

跟缓存击穿解决思路一致,大量请求只有第一个请求获得到锁才能查询数据库,然后将数据写入redis后释放锁,其他请求直接查缓存。

解决方案2:将key的过期时间随机化

打乱key的过期时间,避免大批量的key同时过期,这样就不会有大量请求同一时间都查询数据库。或者将经常访问的数据的key永远不过期。

解决方案3:使用Redis集群提高可用性

使用Redis主从+哨兵,主Redis失效了或者宕机了,使用哨兵将从机切换成主机,这样就算一个缓存失效了,也有另一个顶上。

解决方案4:数据预热

在正式部署之前,把可能的数据直接写入到缓存中,这样就可避免在系统上线后这些热点数据被大量请求走数据库。

补充:

redis哨兵模式:针对Redis集群,Redis提供了哨兵模式的命令,哨兵是一个独立运行的进程,原理是哨兵通过向Redis集群发送命令,通过Redis服务器返回其状态监控Redis服务器的状态,当哨兵监测到Redis主机宕机,会自动将slave切换成master,然后通过发布订阅模式通知其他服务器,修改配置文件,让他们换主机。

以上知识点记录好,后面遇到问题一定还是需要条件去实操验证呀!

你可能感兴趣的:(数据库,redis,缓存,数据库)