Redis中的缓存穿透、雪崩、击穿的原因以及解决方案(详解)_redis缓存穿透和雪崩
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
一、概述
① 缓存穿透大量请求根本不存在的key下文详解
② 缓存雪崩redis中大量key集体过期下文详解
③ 缓存击穿redis中一个热点key过期大量用户访问该热点key但是热点key过期
穿透解决方案
- 对空值进行缓存
- 设置白名单
- 使用布隆过滤器
- 网警
雪崩解决方案
- 进行预先的热门词汇的设置进行key时长的调整
- 实时调整监控哪些数据是热门数据实时的调整key的过期时长
- 使用锁机制
击穿解决方案
- 进行预先的热门词汇的设置进行key时长的调整
- 实时调整监控哪些数据是热门数据实时的调整key的过期时长
- 使用锁机制
下文进行详解
三者出现的根本原因Redis命中率下降请求直接打在DB上
正常情况下大量的资源请求都会被redis响应在redis得不到响应的小部分请求才会去请求DB这样DB的压力是非常小的是可以正常工作的如下图
如果大量的请求在redis上得不到响应那么就会导致这些请求会直接去访问DB导致DB的压力瞬间变大而卡死或者宕机。如下图
① 大量的高并发的请求打在redis上
② 这些请求发现redis上并没有需要请求的资源redis命中率降低
③ 因此这些大量的高并发请求转向DB数据库服务器请求对应的资源
④ DB压力瞬间增大直接将DB打垮进而引发一系列“灾害”
那么为什么redis会没有需要访问的数据呢通过分析大致可以总结为三种情况也就对应着redis的雪崩、穿透和击穿下文开始进行详解
问题名称 | 缓存穿透 | 缓存击穿 | 缓存雪崩 |
资源是否存在DB数据库服务器中 | × | √ | √ |
资源是否存在Redis中 | × | × | × |
redis没有对应资源的原因 | 根本不存在该资源DB也没有 | 某个热点key过期 | 大部分key集体过期 |
根本原因 | 大量的高并发的请求打在Redis上但是发现Redis中并没有请求的数据redis的命令率降低所以这些请求就只能直接打在DB数据库服务器上在大量的高并发的请求下就会导致DB直接卡死、宕机 |
二、情景分析 详解
缓存穿透
缓存穿透产生的原因请求根本不存在的资源DB本身就不存在Redis更是不存在
举例情景在线客户端发送大量的不可响应的请求如下图
当大量的客户端发出类似于http://localhost:8080/user/19833?id=-3872 的请求就可能导致出现缓存穿透的情况。因为数据库DB中本身就没有id=-3872的用户的数据所以Redis也没有对应的数据那么这些请求在redis就得不到响应就会直接打在DB上导致DB压力过大而卡死情景在线或宕机。
缓存穿透很有可能是黑客攻击所为黑客通过发送大量的高并发的无法响应的请求给服务器由于请求的资源根本就不存在DB就很容易被打垮了。
解决方式
- 对空值进行缓存
类似于上面的例子虽然数据库中没有id=-3872的用户的数据但是在redis中对他进行缓存key=-3872value=null这样当请求到达redis的时候就会直接返回一个null的值给客户端避免了大量无法访问的数据直接打在DB上
- 实时监控
对redis进行实时监控当发现redis中的命中率下降的时候进行原因的排查配合运维人员对访问对象和访问数据进行分析查询从而进行黑名单的设置限制服务拒绝黑客攻击
- 使用布隆过滤器
使用BitMap作为布隆过滤器将目前所有可以访问到的资源通过简单的映射关系放入到布隆过滤器中哈希计算当一个请求来临的时候先进行布隆过滤器的判断如果有那么才进行放行否则就直接拦截
- 接口校验
类似于用户权限的拦截对于id=-3872这些无效访问就直接拦截不允许这些请求到达Redis、DB上。
注意事项
- 使用空值作为缓存的时候key设置的过期时间不能太长防止占用太多redis资源
- 使用空值作为缓存只能防止黑客重复使用相同的id暴力攻击但是如果黑客使用动态的无效id攻击就没有效果需要配合网警
- 使用布隆过滤器也是有哈希冲突的可能
缓存雪崩
缓存雪崩产生的原因redis中大量的key集体过期
举例
当redis中的大量key集体过期可以理解为redis中的大部分数据都被清空了失效了那么这时候如果有大量并发的请求来到那么redis就无法进行有效的响应命中率急剧下降请求就都打到DB上了到时DB直接崩溃
解决方式
- 将失效时间分散开
通过使用自动生成随机数使得key的过期时间是随机的防止集体过期
- 使用多级架构
使用nginx缓存+redis缓存+其他缓存不同层使用不同的缓存可靠性更强
- 设置缓存标记
记录缓存数据是否过期如果过期会触发通知另外的线程在后台去跟新实际的key
- 使用锁或者队列的方式
如果查不到就加上排它锁其他请求只能进行等待
缓存击穿
产生缓存雪崩的原因redis中的某个热点key过期但是此时有大量的用户访问该过期key
举例
类似于“某男明星塌房事件”上了热搜这时候大量的“粉丝”都在访问该热点事件但是可能优于某种原因redis的这个热点key过期了那么这时候大量高并发对于该key的请求就得不到redis的响应那么就会将请求直接打在DB服务器上导致整个DB瘫痪。
解决方案
- 提前对热点数据进行设置
类似于新闻、某博等软件都需要对热点数据进行预先设置在redis中
- 监控数据适时调整
监控哪些数据是热门数据实时的调整key的过期时长
- 使用锁机制
最后的防线当热点key过期那么就使用锁机制防止大量的请求直接打在DB