面试知识库
进阶

延迟双删方案#

一句话答案#

先删缓存→更新 DB→延迟 N 毫秒→再删缓存,解决主从延迟导致的不一致,更推荐 Canal 监听 binlog 异步删除。

核心要点

流程:

  1. 删除 Redis 缓存
  2. 更新数据库
  3. 延迟 N 毫秒(大于主从同步+一次读耗时)
  4. 再次删除 Redis 缓存

延迟时间评估: 主从延迟 + 一次业务读取耗时 + 冗余(通常几百ms到1s)

更推荐: Canal 监听 binlog 异步删除缓存(无需估算延迟)

面试回答(2分钟版)

延迟双删是解决缓存与数据库一致性的一种策略,核心流程是四步:先删除 Redis 缓存,再更新数据库,然后延迟 N 毫秒,最后再次删除缓存。之所以要延迟二次删除,是因为在读写分离架构下,第一次删缓存后可能有并发读请求从从库读到旧数据并回填到缓存,二次删除就是为了清除这个脏数据。延迟时间需要大于主从同步延迟加一次业务读取耗时,通常设几百毫秒到一秒。但延迟双删只是减少了不一致窗口,并不保证强一致性,而且延迟时间很难精确估算。更推荐的方案是用 Canal 监听 binlog 异步删除缓存,数据库变更后 Canal 捕获 binlog 事件自动触发缓存删除,不需要业务代码估算延迟,可靠性更高。如果二次删除失败,可以配合消息队列做重试保证最终一致。

追问与易错

追问方向:

  • “延迟时间太短/太长分别什么问题?”→ 太短则从库还没同步完,并发读仍可能将旧数据回填缓存,二次删除无效;太长则不一致窗口变大,用户长时间读到旧数据,且增加了系统复杂度
  • “还是可能不一致?什么时候用 Canal?”→ 延迟双删只是缩小不一致窗口,不保证强一致;Canal 监听 binlog 异步删除缓存更可靠,数据库变更后自动触发无需估算延迟,适合对一致性要求较高的场景
  • “第二次删除失败怎么办?”→ 配合消息队列做重试:二次删除失败时将删除消息投递到 MQ,消费端重试删除直到成功;或使用 Canal + MQ 方案,binlog 变更事件天然可重试保证最终一致

易错点:

  • ❌ 延迟双删保证强一致——只减少不一致窗口
  • ❌ 延迟时间随便设——需大于主从延迟+读取时间