欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > 非关系型数据库 八股文 Redis相关 缓存雪崩 击穿 穿透

非关系型数据库 八股文 Redis相关 缓存雪崩 击穿 穿透

2025/4/28 15:15:12 来源:https://blog.csdn.net/qq_30500575/article/details/147460353  浏览:    关键词:非关系型数据库 八股文 Redis相关 缓存雪崩 击穿 穿透

目录

缓存雪崩

大量数据同时过期解决方案

也有可能是 Redis 挂了 故障

缓存击穿

用互斥锁解决

热点数据永远不过期

缓存穿透 重点

可能的原因

限制 请求的 访问

缓存空值或者默认值

布隆过滤器(重要)

总结

参考资料


缓存雪崩

缓存雪崩是指大量缓存数据同时过期

所以我们通常会给 redis 里面的数据随机化过期时间 当缓存数据过期后 用户请求数据 数据不在缓存里 就会重新生成缓存 后续的请求就能直接访问缓存

如果数据大规模过期 用户请求就会全去 mysql mysql 承受不了就会宕机 进而导致整个系统崩溃

redis 故障也会导致缓存雪崩

大量请求也会到 mysql 去

大量数据同时过期解决方案

  1. 随机化过期时间

设置缓存数据过期时间随机 用 伪随机数 设置时间

  1. 互斥锁

互斥锁 这个做法是如果发现 redis 没有数据 加一个互斥锁 则在同一时间内 只让一个线程去构建缓存 这样就不用所有请求都到 mysql 了 当这个线程构建缓存结束后 释放锁 其他线程的请求此时就会进来 获取新的缓存

  1. 异步处理

可以让缓存一直存在 即使过期了 也很快更新 我们可以设置一个定时任务 在后台检测缓存是否存在 如果不存在则更新 尽量保证每次用户访问数据的时候 缓存都是存在的 同样的我们也可以使用消息队列 业务线程发现缓存失效 通过消息队列发一条消息通知后台线程更新缓存

  1. 缓存预热

我们在业务上线的时候 最好进行缓存预热 先把缓存加载起来

也有可能是 Redis 挂了 故障

  1. 服务熔断 请求限流

redis 挂了则直接返回错误 不要访问数据库 但这样会让业务无法工作

限流也可以 请求太多了就直接拒绝服务 直到正常

  1. 构建集群

构建 redis 集群

缓存击穿

假设我们有热点数据

在高并发场景下获取热点数据

热点数据过期的一瞬间 大量高并发请求会直接到 mysql

然后系统就挂了

我感觉缓存击穿是缓存雪崩的一个子集

用互斥锁解决

还是在业务线程请求数据的时候 如果发现缓存里没有数据 就加上互斥锁 保证此时间只有业务线程去数据库获取数据再回来更新缓存 然后释放锁 让其他线程去拿缓存里的数据

如果未能拿到互斥锁的请求 要不返回空值 要不继续等

热点数据永远不过期

永不过期

如果数据库数据更新了再通知缓存

可以用消息队列实现

缓存穿透 重点

之前我们说的是 缓存雪崩 缓存击穿 这两种情况

那么说明还是有数据的 我们只是要求缓存恢复相对应的数据 即可正常运行

但是如果 数据库没有数据 缓存也没有数据

后续的请求依旧会全部到达缓存 导致数据库压力骤增

为什么会存在 数据库中也没有数据 缓存中也没有数据这种情况呢

可能的原因

  1. 业务误操作 删掉了 mysql 和缓存里面的数据
  2. 黑客恶意攻击 特地访问不存在的数据

限制 请求的 访问

在 API 的入口处我们要判断请求参数是否合理

请求参数是否包含非法值 是否存在

让恶意请求不会到达数据库和缓存 直接被拦截

缓存空值或者默认值

当我们线上业务发现存在缓存穿透

可以在缓存里面提前设置一个空值或者是默认值

这样后续请求到达缓存的时候就能读取空值或者默认值 返回给应用

而不会继续查询数据库

布隆过滤器(重要)

布隆过滤器是一个位数组

通过 k 个函数对数据进行哈希计算

得到 k 个结果

然后将结果作为索引

将对应索引处的值标记为 1

数据传入同样是进行 k 个哈希运算

如果这 k 个位置的数值都是 1 那么表示数据已经出现过了

布隆过滤器主要反馈的是两个信息

  1. 数据可能出现过 (因为可能会存在哈希冲突)
  2. 数据一定没有出现

布隆过滤器说数据存在 可能存在 也可能不存在

但是布隆过滤器说数据不存在 那就是不存在

进入缓存查数据的时候 在要进入数据库查询数据返回更新缓存的时候 我们可以使用布隆过滤器查看数据库中是否存在数据

总结

参考资料

什么是缓存雪崩、击穿、穿透? | 小林coding

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com