高 进阶
延迟双删方案#
一句话答案#
先删缓存→更新 DB→延迟 N 毫秒→再删缓存,解决主从延迟导致的不一致,更推荐 Canal 监听 binlog 异步删除。
核心要点
流程:
- 删除 Redis 缓存
- 更新数据库
- 延迟 N 毫秒(大于主从同步+一次读耗时)
- 再次删除 Redis 缓存
延迟时间评估: 主从延迟 + 一次业务读取耗时 + 冗余(通常几百ms到1s)
更推荐: Canal 监听 binlog 异步删除缓存(无需估算延迟)
面试回答(2分钟版)
延迟双删是解决缓存与数据库一致性的一种策略,核心流程是四步:先删除 Redis 缓存,再更新数据库,然后延迟 N 毫秒,最后再次删除缓存。之所以要延迟二次删除,是因为在读写分离架构下,第一次删缓存后可能有并发读请求从从库读到旧数据并回填到缓存,二次删除就是为了清除这个脏数据。延迟时间需要大于主从同步延迟加一次业务读取耗时,通常设几百毫秒到一秒。但延迟双删只是减少了不一致窗口,并不保证强一致性,而且延迟时间很难精确估算。更推荐的方案是用 Canal 监听 binlog 异步删除缓存,数据库变更后 Canal 捕获 binlog 事件自动触发缓存删除,不需要业务代码估算延迟,可靠性更高。如果二次删除失败,可以配合消息队列做重试保证最终一致。
追问与易错
追问方向:
- “延迟时间太短/太长分别什么问题?”→ 太短则从库还没同步完,并发读仍可能将旧数据回填缓存,二次删除无效;太长则不一致窗口变大,用户长时间读到旧数据,且增加了系统复杂度
- “还是可能不一致?什么时候用 Canal?”→ 延迟双删只是缩小不一致窗口,不保证强一致;Canal 监听 binlog 异步删除缓存更可靠,数据库变更后自动触发无需估算延迟,适合对一致性要求较高的场景
- “第二次删除失败怎么办?”→ 配合消息队列做重试:二次删除失败时将删除消息投递到 MQ,消费端重试删除直到成功;或使用 Canal + MQ 方案,binlog 变更事件天然可重试保证最终一致
易错点:
- ❌ 延迟双删保证强一致——只减少不一致窗口
- ❌ 延迟时间随便设——需大于主从延迟+读取时间