← 中文资源

简体中文版本

双写问题

双写指在同一代码路径里更新两个系统——数据库加缓存、数据库加队列——两步之间的崩溃留下任何重试都无法察觉的永久分歧。

阅读英文原文

概念定义

两个系统、一次逻辑变更、没有共享原子性。两次写入之间的代码就是窗口:崩溃即半途而废——而且没有任何日志说明是哪一半。

工作机制

失败分两态:库已提交、发布丢失——下游永远不知道;发布已发、库回滚了——下游收到谎言。两者都静默。发件箱模式把事件做成与状态同事务的一行,由中继异步发布并重试到送达;CDC 变体改读 WAL,让数据库本身成为事件之源。

使用场景

二级存储必须跟随主存储的一切场景:缓存、搜索索引、分析事件、webhook 扇出。审计准则:任何一对顺序变更调用都是双写嫌疑。

常见误区

给两步都套重试会重复执行已成功的那步,把分歧推向另一个方向。2PC 确实提供原子性,代价是多数系统拒绝的可用性与吞吐——发件箱两头都不付。最终一致也救不了:收敛需要“真值可收敛”,双写恰恰没有记录“本应发生什么”。旁路缓存模式用 TTL 陈旧性绕开双写,比假装原子失效诚实得多。