🌴 缓存穿透 击穿 雪崩 一致性
2022年10月10日
- db
🌴 缓存穿透 击穿 雪崩 一致性
1. 缓存穿透
原因
- 请求的数据不在 缓存 中,相当于 缓存 没有发挥 该有的作用
解决措施
- 对请求数据进行 参数校验,验证其 合法性,防止 恶意攻击
- 对于 null 的返回数据,短暂存入 Redis 中
- 添加 布隆过滤器,对所有可能请求存入 布隆过滤器 中,对于请求,首先判断 布隆过滤器 中是否存在,如果不存在,直接返回 null
2. 缓存击穿
原因
- 某个热点 key 失效,导致大量请求全部打到数据库
解决措施
- 设置 热点数据 永不过期
- 添加 互斥锁
3. 缓存雪崩
原因
- 大量 key 同一时间失效,导致请求全部打到数据库
解决措施
- 过期时间
- 防止大量 key 同一时间失效,给过期时间添加 随机数
- 热点数据永不过期,而是进行 key 的更新
- 提高可用性
- 集群部署
- 设置多级缓存
- Redis 缓存 + 本地缓存
- 熔断降级
- 熔断
- 暂停该业务访问缓存系统
- 降级
- 业务内部暂时舍弃一些非核心的接口 & 数据的请求,而是返回一个提前准备好的 错误处理信息
- 熔断
4. 缓存一致性
1) 出现原因
- 缓存 key 删除失败,但是 数据库中仍存在
- 先删数据库,后删缓存,缓存删除失败
- 并发导致写入脏数据
- 先删缓存,后更新数据库时,由于缓存不存在,读入数据库旧值,又更新到缓存,导致缓存中存放的是 旧值
2) 如何解决
- 消息队列保证 key 被删除
- 借助 消息队列 的重试机制
- 数据库订阅 + 消息队列 保证 key 被删除
- 业务更新数据库后,写入 binlog
- 使用
canal
等中间件监听数据库的 binlog,获取需要操作的数据 - 开启一个非业务服务,订阅操作数据,对 Redis 进行删除
- 延时双删防止脏数据
- 延时时间需要进行 测试
3) 本地缓存 & 分布式缓存的一致性
- 分布式缓存通过 Redis 实现,要删除某个 key,可以保证分布式缓存的一致性
- 本地缓存存在 各个分布式 服务自己的内存中
- 查询时,先查询 本地缓存,再查询 分布式缓存,最后是 数据库
- 如何保证 各个分布式服务 中某个 key 的删除?
- 消息队列
- 本地缓存设置相对短的过期时间