Redis缓存雪崩、穿透、击穿
解决方案
布隆过滤器,分布式锁
正常的缓存流程
1. Redis缓存雪崩
Redis中的key大面积失效,导致软件直接和数据库进行沟通,把请求都打到了数据库上。这就是缓存雪崩,大量的redis在同一时间失效。
Redis缓存雪崩解决方案
- 设置缓存的失效时间,让它不要在同一时间失效。
- 在我们设置这个缓存的时候,随机初始化它的失效时间,这样的话就不会让所有缓存在同一时间失效,把所有请求都打到数据库上。
- redis一般都是集群部署,我们将热点的key放到不同的节点上去。让热点的缓存平均分布在不同的redis节点上。
- 不设置缓存失效的时间。
- 跑定时任务,定时刷缓存,例如缓存设置了三小时时效,在时效之前,把redis缓存给他重新跑进去,然后再设置三小时,不断地用这个定时任务去刷新这个缓存,这个缓存就不会失效。
2. Redis缓存穿透
数据库的主键就是从0开始递增的,没有负数。黑客不断利用id小于零的这个参数发请求。redis中查不到便会不断地将这个请求打到数据库上。
redis直接被这种数据穿透了,恶意用户去请求软件,然后用这个id等于负一的数据去请求。redis和数据库都没有这样的数据,一般出现这种情况都不是正常的用户,而是一些恶意的用户。
简洁版:一个用户去访问一个不存在的键,不只是一个用户,很多很多个请求都访问这样一个不存在的键,然后这个缓存中没有,所以它所有请求都会发送到那个MySQL上。这样的话,数据库压力太大了,就可能造成崩溃。
Redis缓存穿透解决方案
- 这个请求穿透redis到这个数据库,数据库无论查出什么请求,空或者有值都会缓存到redis中去。这样下次用同一个参数来发请求的时候,就不会穿透这个redis。但是他可能会换不同的参数。
- 拉黑IP,但是对方也可能更换不同的IP。
- 对参数的合法性检验,再判断这个参数不合法的时候,直接return掉。
- 使用布隆过滤器。
布隆过滤器的原理
布隆过滤器是一种空间效率很高的数据结构,它利用位数组和哈希函数来判断一个元素是否存在于集合中,具有高效的插入和查询操作。其基本思想是:对于每个元素,使用k个独立的哈希函数将其映射到位数组中的k个位置上,然后将这些位置标记为1。查询时,对于每一个元素,同样地将其映射到位数组上的k个位置,若所有位置都被标记为1,则说明该元素可能存在于集合中,若存在任意一个位置未被标记为1,则该元素一定不存在于集合中。
简洁版:使用了哈希,它正常的哈希就是一个哈希函数,但是它是使用了很多很多的hash函数。比如说它的hash函数是对应一个数组的,一个请求进行哈希之后,会得到不同的索引。然后它去索引位判断是否出现过。默认情况下它是0的,然后存在的话它是1。如果全是1的话,代表它可能会出现过。如果其中有一个0的话,那么就代表它就是不符合的,这个是不存在的。
3. Redis缓存击穿
大量的用户请求去不断地访问这个热点的key,当这个热点的key突然失效,把请求打到数据库上,这个过程就叫做击穿。他是击穿一个非常热点的key。
Redis缓存击穿解决方案
- 让这个缓存永远不过期。
- 使用分布式锁。如果是单体应用的话,就可以使用互斥锁。
请求数据库这一步上锁,只有拿到锁的线程可以操作这个数据库。这个时候对数据库的压力就非常小。当他查询到这个数据之后再将缓存重新写到redis里面去。其他没有抢到锁的数据让他先睡几毫秒,然后再重新去redis里面去查询数据。
总结
雪崩:key大面积失效。
穿透:访问没有的数据(例如id小于0)。
击穿:不断访问热点key,直到key失效。