Redis中的缓存穿透、雪崩、击穿的原因以及解决方案

Redis中的缓存穿透、雪崩、击穿的原因以及解决方案

万能青年
2023-05-12 / 0 评论 / 121 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2023年05月13日,已超过519天没有更新,若内容或图片失效,请留言反馈。

缓存穿透

大量请求根本不存在的key

解决方案

  • 对空值进行缓存
  • 设置白名单
  • 使用布隆过滤器
  • 网警

缓存雪崩

redis中大量key集体过期

解决方案

  • 进行预先的热门词汇的设置,进行key时长的调整
  • 实时调整,监控哪些数据是热门数据,实时的调整key的过期时长
  • 使用锁机制

缓存击穿

redis中一个热点key过期 (大量用户访问该热点key,但是热点key过期)

解决方案

  • 进行预先的热门词汇的设置,进行key时长的调整
  • 实时调整,监控哪些数据是热门数据,实时的调整key的过期时长
  • 使用锁机制(只有一个线程可以进行热点数据的重构)

三者出现的根本原因:

Redis命中率下降,请求直接打在DB上

正常情况下,大量的资源请求都会被redis响应,在redis得不到响应的小部分请求才会去请求DB,这样DB的压力是非常小的,是可以正常工作的

lhkpu0h9.png

如果大量的请求在redis上得不到响应,那么就会导致这些请求会直接去访问DB,导致DB的压力瞬间变大而卡死或者宕机

lhkpw7vc.png

问题名称缓存穿透缓存击穿缓存雪崩
资源是否存在DB数据库服务器中×
资源是否存在Redis中×××
redis没有对应资源的原因根本不存在该资源(DB也没有)某个热点key过期大部分key集体过期

根本原因

大量的高并发的请求打在Redis上,但是发现Redis中并没有请求的数据,redis的命令率降低,所以这些请求就只能直接打在DB(数据库服务器)上,在大量的高并发的请求下就会导致DB直接卡死、宕机

情景分析

#缓存穿透

缓存穿透产生的原因:请求根本不存在的资源(DB本身就不存在,Redis更是不存在)

例:客户端发送大量的不可响应的请求

lhkqgnbt.png

解决方式

  • 对空值进行缓存
类似于上面的例子,虽然数据库中没有id=-100的用户的数据,但是在redis中对他进行缓存(key=-100,value=null),这样当请求到达redis的时候就会直接返回一个null的值给客户端,避免了大量无法访问的数据直接打在DB上
  • 实时监控
对redis进行实时监控,当发现redis中的命中率下降的时候进行原因的排查,配合运维人员对访问对象和访问数据进行分析查询,从而进行黑名单的设置限制服务(拒绝黑客攻击)
  • 使用布隆过滤器
使用BitMap作为布隆过滤器,将目前所有可以访问到的资源通过简单的映射关系放入到布隆过滤器中(哈希计算),当一个请求来临的时候先进行布隆过滤器的判断,如果有那么才进行放行,否则就直接拦截
  • 接口校验
类似于用户权限的拦截,对于id=-100这些无效访问就直接拦截,不允许这些请求到达Redis、DB上。

#注意事项

  • 使用空值作为缓存的时候,key设置的过期时间不能太长,防止占用太多redis资源
  • 对空值缓存是一种被动的防御方式,当遇到黑客暴力请求很多不存在的数据就需要写入大量的null值到Redis中,可能导致Redis内存占用不足的情况
  • 使用布隆过滤器,可以在用户访问的时候判断该资源是否存在,不存在则直接拒绝访问
  • 布隆过滤器是有一定的误差,所以一般需要配合一些接口流量的限制(规定用户在一段时间内访问的频率)、权限校验、黑名单等来解决缓存穿透的问题

#缓存雪崩

#解决方式

  • 将失效时间分散开
通过使用自动生成随机数使得key的过期时间是随机的,防止集体过期
  • 使用多级架构
使用nginx缓存+redis缓存+其他缓存,不同层使用不同的缓存,可靠性更强
  • 设置缓存标记
记录缓存数据是否过期,如果过期会触发通知另外的线程在后台去跟新实际的key
  • 使用锁或者队列的方式
如果查不到就加上排它锁,其他请求只能进行等待

#缓存击穿

#解决方案

  • 提前对热点数据进行设置
类似于新闻、某博等软件都需要对热点数据进行预先设置在redis中
  • 监控数据,适时调整
监控哪些数据是热门数据,实时的调整key的过期时长
  • 使用锁机制
只有一个请求可以获取到互斥锁,然后到DB中将数据查询并返回到Redis,之后所有请求就可以从Redis中得到响应
3

评论 (0)

取消