缓存雪崩 缓存击穿 缓存雪崩出现原因及解决方案
作者:互联网
文章目录
缓存雪崩
出现原因一
解决方案
方案一 差异化设置过期时间
方案二 服务降级
方案三 不设置过期时间
出现原因二
解决方案
方案一 服务熔断
方案二 请求限流
方案三 Redis构建高可靠集群
缓存击穿
解决方案
方案一 分布式锁
方案二 热点数据不设置过期时间
缓存穿透
出现原因
解决方案
方案一 设置缺省值
方案二 使用布隆过滤器过滤数据
缓存雪崩
大量的应用请求无法在Redis缓存中进行处理,紧接着应用将大量请求发送到数据库层,导致数据库层的压力激增
缓存雪崩一般有两个原因导致,解决方案也有所不同
出现原因一
缓存中有大量Key同时过期,导致大量请求无法得到处理,大量数据需要回源数据库
解决方案
方案一 差异化设置过期时间
差异化缓存过期时间,不要让大量的 Key 在同一时间过期。比如,在初始化缓存的时候,给这些数据的过期时间增加一个较小的随机数,这样一来不同数据的过期时间有所差别又差别不大,即避免了大量数据同时过期又能保证这些数据在相近的时间失效
方案二 服务降级
允许核心业务访问数据库,非核心业务直接返回预定义的信息
方案三 不设置过期时间
初始化缓存数据的时候设置缓存永不过期,然后启动一个后台线程 30 秒一次定时把所有数据更新到缓存,而且通过适当的休眠,控制从数据库更新数据的频率,降低数据库压力。
出现原因二
Redis实例发生故障宕机,无法处理请求,就会导致大量请求积压到数据库层
解决方案
方案一 服务熔断
暂停业务应用对缓存服务的访问,从而降低对数据库的压力
方案二 请求限流
控制每秒进入应用程序的请求数,避免过多的请求被发到数据库
方案三 Redis构建高可靠集群
通过主从节点的方式构建Redis高可靠集群。可以保证在Redis主节点故障宕机时,从节点切换到主节点,继续提供服务,避免由于缓存实例宕机导致缓存雪崩
缓存击穿
热点数据在某一时刻过期了,可能会导致随之而来的大量的并发请求直接打到数据库,导致数据库压力激增。
解决方案
方案一 分布式锁
采用锁机制控制打到数据库的请求,读取数据后将其写回到缓存,保证了其他线程可以命中缓存。
//伪代码 加锁成功; result=redis.getKey(X); if(result==null){ result=db.getData(X); redis.setData(X,result); } 释放锁;
方案二 热点数据不设置过期时间
缓存穿透
客户端 请求了一个业务程序中不存在的数据,即要访问的数据既不在Redis缓存中,也不在数据库中。导致每次类似的请求,都会先从Redis–>数据库去查数据,最终也无果。
当存在大量请求这样访问时,会同时给缓存和数据库带来很大压力。
出现原因
1、误操作导致:缓存中的数据和数据库中的数据都被误删了
2、恶意攻击:专门访问数据库中不存在的数据
解决方案
方案一 设置缺省值
比如当请求id=1000的用户数据时,在数据库中找不到该条数据,则将NONE这样具有特殊含义的字符串设置到缓存中,后续客户端再请求该数据时,可以直接命中缓存,不再访问数据库。
但是这样有个问题,如果客户端访问大量的不同的数据,那这些大量无效的数据可能会占满缓存
方案二 使用布隆过滤器过滤数据
布隆过滤器由一个初值都为 0 的 bit 数组和 N 个哈希函数组成,可以用来快速判断某个数据是否存在。
工作原理
1、使用 N 个哈希函数,分别计算这个数据的哈希值,得到 N 个哈希值
2、把这 N 个哈希值对 bit 数组的长度取模,得到每个哈希值在数组中的对应位置。
3、标记数据,把对应位置的 bit 位设置为 1
如果数据不存在,那布隆过滤器中bit数组对应的bit位的值为0.
过滤规则:
当一个元素需要被检索时,使用N个哈希函数对该元素求得哈希值,并定位到bit数组中。如果发现对应位置处bit位有任何一个0,就说明这个元素不存在于布隆过滤器;当bit位都是1,说明这个元素可能存在于布隆过滤器(这里说可能,是因为不同元素经过哈希运算可能得到相同的哈希值)
像Guava、Redisson 都有布隆过滤器的实现。
我们只需要初始化布隆过滤器,即将数据添加到布隆过滤器中。然后借助布隆过滤器去判断元素是否存在
参考文献
Redis核心技术与实战
————————————————
版权声明:本文为CSDN博主「码农的进阶之路」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zyxwvuuvwxyz/article/details/122829234
标签:方案,缓存,过期,数据库,击穿,雪崩,哈希,数据 来源: https://www.cnblogs.com/wl-blog/p/16578865.html