延时双删是“先删缓存→写数据库→延迟再删缓存”的最终一致性方案,通过两次删除加合理延迟(通常1–2秒)清除并发读导致的脏数据,适用于读多写少、允许短暂不一致的场景。

延时双删是一种在“先删缓存 → 写数据库 → 延迟再删缓存”流程中,通过时间窗口控制来大幅降低脏数据概率的最终一致性方案。它不追求强一致,但能适配绝大多数读多写少、允许短暂不一致的业务场景(如商品信息、用户资料、内容详情等)。
延时双删的核心步骤
- 第一次删缓存:写请求开始时立即删除 Redis 中对应 key
- 更新数据库:执行 MySQL 的 INSERT/UPDATE/DELETE 操作
- 延迟等待:主动休眠或异步调度一段固定时间(常见 500ms–2s)
- 第二次删缓存:延迟结束后再次删除该 key
这个过程本质是用“可控的写延迟”,换取对并发读请求回填旧值的兜底清除。
为什么两次删除 + 延迟能起作用?
- 第一次删:防止更新前缓存里还存着旧值,被其他读请求直接返回
- 写库后延迟:给正在执行的并发读请求留出时间——它们若已查到旧数据并准备回填缓存,大概率已在这一窗口内完成
- 第二次删:把那些“在第一次删之后、写库完成之前”读到旧值并写入缓存的脏数据,再清掉一次
举个典型并发例子:
线程 A(写):删缓存 → 开始更新 DB
线程 B(读):发现缓存空 → 查 DB(此时还是旧值)→ 回填缓存 → 返回
若 A 在 B 完成回填后立刻二次删,就能及时抹掉这个脏值
所以延迟时长不是拍脑袋定的,要略大于:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 主库写入耗时
- 从库同步延迟(尤其用了读写分离时)
- 一次读 DB + 回填缓存的平均耗时
一般设为 1–2 秒较稳妥;高 SLA 场景可结合监控动态调整。
实际落地要注意的关键点
- 删除操作必须幂等:
DEL key天然幂等,失败重试也安全 - 不要用
SET key value替代删除:更新缓存易引发并发覆盖,且无法解决主从延迟带来的旧值回填问题 - 延迟方式推荐异步化:比如用 DelayQueue、Redis ZSET 定时任务、或消息队列延时投递,避免阻塞主线程影响接口响应
- 必须配合缓存空值/过期策略:万一第二次删失败,靠设置合理 TTL(如 5 分钟)也能兜底,让脏数据自动过期
- 不适合强一致性场景:如账户余额、库存扣减等,这类应走分布式锁或 TCC,而非延时双删
和“先写库再删缓存”的区别
很多人误以为“先写库再删缓存”就够了,但它在以下情况会失效:
- 删缓存失败(网络抖动、Redis 短暂不可用)→ 缓存长期滞留旧值
- 主从同步慢,读请求打到从库拿到旧值,又回填进缓存
延时双删正是对这类异常的补救:即使第一次删失败或没来得及删,第二次还有机会;即使第一次删成功但读请求抢在写完前回填了旧值,延迟后还能清理。
不复杂但容易忽略

















