🌴 缓存穿透 击穿 雪崩 一致性

吞佛童子2022年10月10日
  • db
  • Redis
大约 2 分钟

🌴 缓存穿透 击穿 雪崩 一致性

1. 缓存穿透

原因

  • 请求的数据不在 缓存 中,相当于 缓存 没有发挥 该有的作用

解决措施

  • 对请求数据进行 参数校验,验证其 合法性,防止 恶意攻击
  • 对于 null 的返回数据,短暂存入 Redis 中
  • 添加 布隆过滤器,对所有可能请求存入 布隆过滤器 中,对于请求,首先判断 布隆过滤器 中是否存在,如果不存在,直接返回 null

2. 缓存击穿

原因

  • 某个热点 key 失效,导致大量请求全部打到数据库

解决措施

  • 设置 热点数据 永不过期
  • 添加 互斥锁

3. 缓存雪崩

原因

  • 大量 key 同一时间失效,导致请求全部打到数据库

解决措施

  • 过期时间
    • 防止大量 key 同一时间失效,给过期时间添加 随机数
    • 热点数据永不过期,而是进行 key 的更新
  • 提高可用性
    • 集群部署
    • 设置多级缓存
      • Redis 缓存 + 本地缓存
  • 熔断降级
    • 熔断
      • 暂停该业务访问缓存系统
    • 降级
      • 业务内部暂时舍弃一些非核心的接口 & 数据的请求,而是返回一个提前准备好的 错误处理信息

4. 缓存一致性

1) 出现原因

  1. 缓存 key 删除失败,但是 数据库中仍存在
    • 先删数据库,后删缓存,缓存删除失败
  2. 并发导致写入脏数据
    • 先删缓存,后更新数据库时,由于缓存不存在,读入数据库旧值,又更新到缓存,导致缓存中存放的是 旧值

2) 如何解决

  1. 消息队列保证 key 被删除
    • 借助 消息队列 的重试机制
  2. 数据库订阅 + 消息队列 保证 key 被删除
    • 业务更新数据库后,写入 binlog
    • 使用 canal 等中间件监听数据库的 binlog,获取需要操作的数据
    • 开启一个非业务服务,订阅操作数据,对 Redis 进行删除
  3. 延时双删防止脏数据
    • 延时时间需要进行 测试

3) 本地缓存 & 分布式缓存的一致性

  1. 分布式缓存通过 Redis 实现,要删除某个 key,可以保证分布式缓存的一致性
  2. 本地缓存存在 各个分布式 服务自己的内存中
  3. 查询时,先查询 本地缓存,再查询 分布式缓存,最后是 数据库
  4. 如何保证 各个分布式服务 中某个 key 的删除?
    • 消息队列
    • 本地缓存设置相对短的过期时间
上次编辑于: 2022/10/10 下午8:43:48
贡献者: liuxianzhishou