redis(4) 击穿 穿透 雪崩

1. redis 击穿

原来有,后来失效了。击穿了

当redis作为缓存使用时,当key由于 失效时间过期 或者 LRU LFU算法 使得redis总的key失效后,突然有了高并发,此时,redis中没有这个key,到时并发去数据库获取数据。相当于击穿了redis,到数据库上了

解决的办法。

方法1: setnx  设置锁

假设有3个线程同时到达。

1. 先去get  key  获取目标key 。此时获取的为nli

2. 设置锁 ,setnx  lockkey  lockvalue。 setnx 调用,当没有lockkey时才会创建成功,如果有,就不能创建。也就是说,只有setnx成功后,才能取访问数据库

可能三个线程都去get key都没有取到,由于redis是单线程的,所有只可能有一个线程setnx成功。其他的正在等待,知道第一个线程释放锁后,后面的线程才能够setnx成功。

3. 获取到锁的线程才能访问数据库。

以上方式也会有新的问题:

如果第一个线程获取到锁后,突然线程挂了怎么办。此时后面的线程就拿不到锁。

此时,我们可以给锁设置一个过期时间。当时间到了也能释放锁。

但是如果,线程没有挂,过期时间到了,锁已近释放了,但是查询数据库还没有结束,此时接下来的线程都会卡到查询数据这一步

解决办法: 一个线程取查询数据库

另一个线程监控是否数据取回来了,如果锁过期还没取回来,则更新锁的过期时间。

方法二: 设置热点数据用不过期

方法三:利用布隆过滤器

  1. 利用过滤器,布隆过滤器。Bloom Filter,用来判断一个key是否在集合中。

    布隆过滤器原理:和hash表是一样的。
    1. 需要一个bit位的数组,初始值位0,存储的key通过hash函数算出一个数,而这个数就是对应数组中的索引,将该索引位置设置为1,表示这个key是存在的。

    2. 所以将数据库中所有的查询条件放入到布隆过滤器中。

    3. 向查询redis,如果redis没有,查询布隆过滤器,key通过hash函数找到bit数组中的位置,如果该位置为0,表示集合中一定没有该值,直接返回。如果为1,表示这个值有概率在集合中,就可以放过查询数据库。

使用

eg: 1、 将所有数据都添加add到bloom过滤器中。BF.add   所有数据

2. 通过判断是否存在。如果返回为1, 就有可能存在,可以放过去数据库中查询。 BF.exist 判断是否存在,1 有可能有,0一定没有。

如果返回为0,就一定不存在,此时直接返回就可以了。

击穿图 

2. 穿透

本身数据就不存在,直接穿透

1.  就是请求调用获取的key 在redis 和数据库 中都没有。就是业务需要查询的数据,数据库中根本没有,就是空。

解决问题 :

1)布隆过滤器。缺点,不能删除。使用 布谷鸟,可以删除

2)在接口层做一些校验,比如用户鉴权,或者一些范围的校验,进行拦截一部分

3)或者对于获取不到数据的,进行缓存一些null,但是设置的过期时间要小。

3. 雪崩

大量的key同时到期了,大量的key失效。大量的访问到达数据库DB。相当于换血。

雪崩和击穿有点相像。

但是有所区别: 击穿可以理解为个别数据的高并发

雪崩则是大量数据的高并发。

解决办法:1. 随机过期时间。时点性无关时适用

2. 还有一种场景就是,在零点(固定时间点)必须换key,此时就不适用随机过期时间,此时强依赖击穿方案。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值