【redis】缓存击穿、雪崩、穿透

缓存穿透

简介

key对应的数据在数据库和缓存中都不存在,每次针对此key的请求从缓存获取不到,请求都会到数据源,所以当有特别多key不存在的请求到来时,会直接访问数据库,数据库扛不住压力,从而可能压垮数据源。比如用一个不存在的用户id获取用户信息,不论缓存还是数据库都没有,若黑客利用此漏洞进行攻击可能压垮数据库。

解决办法:

1.使用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉,用高效的数据结构和算法快速判断出你这个Key是否在数据库中存在,不存在你return就好了,存在你就去查了DB刷新KV再return。从而避免了对底层存储系统的查询压力。

2.还有一个更为简单粗暴的方法,如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。

3.参数做校验,不合法的请求直接过滤掉。

4.还可以使用nginx,或者拦截器,讲恶意ip直接拉黑。

缓存击穿

简介

key对应的数据是个热点数据,每秒都有大量的请求访问他,但在redis中过期时,此时若有大量并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求会直接到数据库,可能会瞬间把后端DB压垮,就像在一个完好无损的桶上凿开了一个洞。

解决办法

1.设置热点数据永远不过期。

2.加互斥锁(mutex key)

比较常用的做法,是使用mutex。简单地来说,就是在缓存失效的时候(判断拿出来的值为空),不是立即去load db,而是先使用缓存工具的某些带成功操作返回值的操作(比如Redis的SETNX或者Memcache的ADD)去set一个mutex key,当操作返回成功时,再进行load db的操作并回设缓存;否则,就重试整个get缓存的方法。

SETNX,是「SET if Not eXists」的缩写,也就是只有不存在的时候才设置,可以利用它来实现锁的效果。

缓存雪崩

简介

当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,大量的请求来请求这些失效的数据,会直接访问数据库,会给后端系统(比如DB)带来很大压力。比如某商城首页的信息都在缓存中,晚上零点失效,而此时正好商城有一个秒杀活动,我们有大量的用户用户,都会请求首页数据,但是此时首页数据失效了,并发的大量请求会直接访问数据库,如果数据库扛不住压力,会直接挂掉。

同一时间大面积失效,那一瞬间Redis跟没有一样,那这个数量级别的请求直接打到数据库几乎是灾难性的,数据库如果挂掉,其他依赖此库的接口都会报错,如果没有雪崩处理机制,挂掉的不仅仅是秒杀这个模块。如果你重新,新的大量的请求还会把你数据库打挂掉。等你能重启的时候,用户早就睡觉去了,并且对你的产品失去了信心,失去了大量的用户。

解决办法

1.处理缓存雪崩简单,在批量往Redis存数据的时候,把每个Key的失效时间都加个随机值就好了。这样就能避免同一时间大量的redis失效了。

setRedis(Key,value,time + Math.random() * 10000);

2. Redis是集群部署,将热点数据均匀分布在不同的Redis库中也能避免全部失效的问题

3.设置热点数据永远不过期,有更新操作就更新缓存

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值