Redis缓存穿透、击穿和雪崩

缓存、击穿和雪崩都意味着用户访问时,Redis中没有对应的数据,因此Redis命中率下降,请求直接打在DB上。

那么为什么redis会没有需要访问的数据呢?

问题名称缓存穿透缓存击穿缓存雪崩
资源是否存在DB数据库服务器×
资源是否存在Redis中×××
redis没有对应资源的原因根本不存在该资源(DB也没有)某个热点key过期大部分key集体过期
根本原因大量的高并发的请求打在Redis上,但是发现Redis中并没有请求的数据,redis的命令率降低,所以这些请求就只能直接打在DB(数据库服务器)上,在大量的高并发的请求下就会导致DB直接卡死、宕机

① 缓存穿透:大量请求根本不存在的key(下文详解)

② 缓存雪崩:redis中大量key集体过期(下文详解)

③ 缓存击穿:redis中一个热点key过期(大量用户访问该热点key,但是热点key过期

一、缓存雪崩

当某一时刻发生大规模的缓存失效的情况,会有大量的请求进来直接打到DB上面。

redis中大量的key集体过期

当redis中的大量key集体过期,可以理解为redis中的大部分数据都被清空了(失效了),那么这时候如果有大量并发的请求来到,那么redis就无法进行有效的响应(命中率急剧下降),请求就都打到DB上了,到时DB直接崩溃

为什么会出现大量的Key集体失效?

解决方式:
  • 将失效时间分散开

通过使用自动生成随机数使得key的过期时间是随机的,防止集体过期。

  • 使用多级架构

使用nginx缓存+redis缓存+其他缓存,不同层使用不同的缓存,可靠性更强

  • 设置缓存标记

记录缓存数据是否过期,如果过期会触发通知另外的线程在后台去跟新实际的key

  • 使用锁或者队列的方式

如果查不到就加上排它锁,其他请求只能进行等待

在这里插入图片描述

在这里插入图片描述

二、缓存穿透

用户不断发起请求‘缓存和数据库中’都没有的数据。
我们数据库的 id 都是1开始自增上去的,如发起为id值为 -1 的数据或 id 为特别大不存在的数据。每次都能绕开Redis直接打到数据库,数据库也查不到,每次都这样,并发高点就容易崩掉了

当大量的客户端发出类似于:http://localhost:8080/user/19833?id=-3872 的请求,就可能导致出现缓存穿透的情况。因为数据库DB中本身就没有id=-3872的用户的数据,所以Redis也没有对应的数据,那么这些请求在redis就得不到响应,就会直接打在DB上,导致DB压力过大而卡死情景在线或宕机。

​ 缓存穿透很有可能是黑客攻击所为,黑客通过发送大量的高并发的无法响应的请求给服务器,由于请求的资源根本就不存在,DB就很容易被打垮了。

解决方式:
  • 缓存空值

类似于上面的例子,虽然数据库中没有id=-3872的用户的数据,但是在redis中对他进行缓存(key=-3872,value=null),这样当请求到达redis的时候就会直接返回一个null的值给客户端,避免了大量无法访问的数据直接打在DB上

  • 实时监控:

    对redis进行实时监控,当发现redis中的命中率下降的时候进行原因的排查

  • 使用布隆过滤器

使用BitMap作为布隆过滤器,将目前所有可以访问到的资源通过简单的映射关系放入到布隆过滤器中(哈希计算),当一个请求来临的时候先进行布隆过滤器的判断,如果有那么才进行放行,否则就直接拦截(类似于先通过中间件来进行鉴权)

  • 接口校验

类似于用户权限的拦截,对于id=-3872这些无效访问就直接拦截,不允许这些请求到达Redis、DB上。

三、缓存击穿

缓存击穿是指一个Key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个Key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个完好无损的桶上凿开了一个洞。

产生缓存击穿的原因:redis中的某个热点key过期,但是此时有大量的用户访问该过期key

举例:

​ 类似于“某男明星塌房事件”上了热搜,这时候大量的“粉丝”都在访问该热点事件,但是可能由于某种原因,redis的这个热点key过期了,那么这时候大量高并发对于该key的请求就得不到redis的响应,那么就会将请求直接打在DB服务器上,导致整个DB瘫痪。

解决方案:
  • 提前对热点数据进行设置

类似于新闻、微博等软件都需要对热点数据进行预先设置在redis中

  • 监控数据,适时调整

监控哪些数据是热门数据,实时的调整key的过期时长

  • 使用锁机制

只有一个请求可以获取到互斥锁,然后到DB中将数据查询并返回到Redis,之后所有请求就可以从Redis中得到响应

监控哪些数据是热门数据,实时的调整key的过期时长

  • 使用锁机制

只有一个请求可以获取到互斥锁,然后到DB中将数据查询并返回到Redis,之后所有请求就可以从Redis中得到响应

(派一个请求获取互斥锁,然后去数据库中查询数据并返给Redis,这样后面的请求就可以直接从Redis读取了)

参考: Redis中的缓存穿透、雪崩、击穿的原因以及解决方案(详解)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值