Redis缓存三兄弟(击穿、穿透、雪崩)

1、缓存穿透:

缓存穿透:查询一个不存在的数据,MySQL查询不到的数据也不会直接写入缓存,就会导致每次请求都查询数据库,使得数据库访问压力过大,产生异常甚至宕机。

解决方案:

a、缓存空数据,查询返回的数据为空也要把这个空结果写进缓存        {key:1,value:null}

(优点:)这种方式简单方便(缺点:)但如果数据有很多都是null就会占用太多内存同时如果一个数据存入缓存为null,但之后在数据库中插入了这个数据,这样就会产生数据不一致的问题。

b、使用布隆过滤器。

开始时会从数据库中向redis批量缓存一些数据同时布隆过滤器也要缓存一些数据。

布隆过滤器使用bitmap:是一个以bit为单位的数组,数组中每个单元只存二进制数0或1。

作用:可以检索一个元素是否在一个集合中。

存数据:假设id为1的数据,通过多个hash函数获取hash值,根据hash计算数组对应的位置并把0改为1。

取数据:使用相同的hash函数获取hash值,并判断对应位置是否全为1。

但布隆过滤器是有误判发生的,如果一个元素多次hash计算后对应的数组的位置刚好是其他多个元素已经hash后的改为1的位置,这样就会产生误判,当然这个误判我们是可以设置的,在bloomFilter.tryInit(size ,0.05);中设置误判率为0.05。误判不可能不存在,我们只能改变误判率。数组越小误判率越大,数组越大误判率越小但随之而来的就是内存压力。

2、缓存击穿

缓存击穿:给某一个key设置了过期时间,当key过期时,恰好这个点对这个key有大量的并发请求,这些并发请求可能会瞬间压垮数据库。(一般我们在开发时对数据库的查询都是复杂的往往需要多表查询,这些查询会消耗很多时间,如果一瞬间有大量的请求则数据库会瞬间被压垮)

解决方案:

a、互斥锁

当缓存失效时,不立即去加载数据库,先使用redis的setnx去设置一个互斥锁,当操作成功返回时再进行加载数据库并回设缓存,否则重试get缓存的方法。

b、设置key逻辑过期

1、在设置key的时候,设置一个过期时间字段一块存入缓存中,不给当前key设置过期时间

2、当查询的时候,从redis取出数据后判断时间是否过期

3、如果过期则开通另外一个线程进行数据同步,当前线程正常返回数据,这个数据不是最新的数据。

区别:

互斥锁是强一致性,但性能不高,毕竟需要等待锁的释放,也可能产生死锁问题;

key逻辑删除是高可用性,性能较高,但数据同步做不到强一致。

3、缓存雪崩

缓存雪崩意思是设置缓存时采用了相同的过期时间,导致缓存在某一时刻同 时失效,请求全部转发到DB,DB 瞬时压力过重雪崩。与缓存击穿的区别: 雪崩是很多key,击穿是某一个key缓存。
解决方案:
主要是可以将缓存失效时间分散开,比如可以在原有的失效时间基
础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重
复率就会降低,就很难引发集体失效的事件。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值