DDIA 导读 CH 6 — 复制 (下)

2026年10月12日

💎 加入 E+ 會員方案 與超過千位工程師一同在社群成長,並獲得更多深度的軟體前後端學習資源

DDIA 导读 CH 6 — 复制 (上) 中讨论了数据系统中的复制概念,以及单主节点复制这个最基本的复制架构。在 DDIA 第六章的后半部分,作者进一步讨论了多主节点 (multi-leader replication) 与无主节点 (leaderless replication) 的复制方式。

多主节点复制

单主节点复制的主要缺点之一,是所有写入都需要经过同一个主节点;这意味着如果该主节点发生故障或无法连接,就无法向数据库写入任何新内容。试想,假如亚洲的副本数据库运行良好,但美洲的主数据库连接不上,这时就会出现眼前的数据库明明正常,却无法写入的尴尬情况。

这也是多主节点复制出现的原因之一。只有一个主数据库时,可能会因单个节点的问题而受阻,那么如果增加几个能接受写入的节点,也许就能解决这个问题。

简单来说,单主节点复制是这样的:

写入 → 只能写入主数据库

读取 → 可以读取主库或从库

相比之下,多主节点复制则是这样的:

写入 → 可以写入主数据库 A,也可以写入主数据库 B,也可以写入主数据库 C

读取 → 也可以从这些节点读取

每个能接受写入的节点,都可以算是主数据库;当某个主数据库收到写入请求后,会再把变更同步到其他主数据库。因此,从定义上看,某个主数据库同时也会作为副本数据库存在。

需要特别注意的是,在多区域部署的系统中,通常每个区域会有一个主数据库,搭配多个只能读不能写的副本数据库。这种架构的整体复杂度较低。因此,通常会由区域内的主数据库与其他区域的主数据库同步,再把收到的变更同步到区域内的副本数据库。

image

多主节点复制的优点

相比单主节点复制,多主节点复制有多个优点。第一个是性能更好。如果只有一个主节点,跨区域的写入就需要经过较长的网络传输。例如,台湾的一次写入请求要发送给美国的主数据库,较长的物理距离会增加延迟。但如果亚洲区域就有一个主数据库,台湾的写入请求就不必发往美洲,而是就近发给亚洲区域的主数据库,从而降低延迟。

第二个优点是容错能力更强。在单主节点模式下,如果主数据库所在的区域发生故障,系统必须进行跨区域故障转移,把另一个区域的副本数据库提升为主数据库,这个过程较为复杂。相比之下,在多主节点模式下,如果某个区域故障,其他区域的主节点仍能继续接受写入,因此整个系统不一定会像单主节点架构一样停止写入。这种韧性对于要求高可用性的场景尤其有价值。

第三个优点是对跨区域网络故障的容忍能力更强。在单主节点架构下,系统对跨区域网络比较敏感:其他区域的用户写入时,需要跨区域访问主数据库。由于传输路径较长,也可能更容易遇到问题。多主节点架构虽然仍有跨区域同步,但主要发生在不同区域的主节点之间。副本节点与主节点同步时,由于处于同一区域,同步相对不那么容易受到跨区域网络问题的影响。

多主节点复制的难题

虽然多主节点复制有许多优点,但在实践中也有不可避免的难题,其中「一致性」是最大的挑战。

书中提到银行转账的例子。假设某个账户中有 100 元,A 地与 B 地都有主数据库;由于复制存在延迟,两地当下看到的余额都是 100 元。此时,如果两个地方都收到取款 80 元的写入请求,主数据库 A 可能认为没问题,因为 80 小于 100;主数据库 B 也会做出同样的判断。

两边单独看都没问题,但如果合在一起,两笔写入就会变成 100 - 80 - 80,也就是 -60,这是不合理的结果。甚至 -60 也不一定是最终结果 (如果采用最后写入者胜出的冲突解决机制),但这里的重点是,系统让两笔 80 的写入都成功了,而实际上不应该如此。

要避免冲突,就需要在写入时通过协调机制进行跨区域通信;然而,跨区域通信意味着延迟增加。这是分布式系统的基本限制,选择多主节点复制就必须面对。因此,在实际工程决策中,需要回头问:对当前系统来说,什么最重要?低延迟更重要,还是跨区域一致性更重要?

在实践中,如果某个场景必须保证全局一致性,就相对不适合选择多主节点复制。例如银行账户余额不能为负、电商库存不能为负,或者售票系统中的一张票不能被多个人买走。在这些场景下,多主节点复制带来的不一致,通常会造成比收益更高的成本。

多主节点复制如何同步数据?

介绍完多主节点复制的优点与难题后,书中进一步讨论了这种模式如何同步数据。书中使用「复制拓扑 Replication Topology」这个词,所谓拓扑,是指变更如何在节点之间传播。常见的多主节点拓扑包括全互联 (all-to-all)、环形 (circular) 与星形 (star),其中全互联最为通用。

image

从上图可以看到,在全互联拓扑中,每个主数据库会把写入直接发送给其他主数据库。这种做法的优点是整体容错能力较强。节点之间有直接路径,所以如果某一条节点间的连接出现问题,其他节点仍能通信,不会因此受阻。

但全互联拓扑的连接数和复杂度都比较高,每个节点需要管理更多同步对象。此外,还会遇到数据同步顺序的问题。不同主数据库通常位于不同区域,网络传输时间也不同。这可能导致客户端先向主数据库 A 写入新数据,再向主数据库 B 更新该数据,但主数据库 B 尚未同步到原始数据,从而出现先更新、后新增的因果顺序颠倒问题。

环形拓扑中,每个节点只把变更同步到下一个节点。相比全互联,这种方式的复杂度低得多,每个节点只需要与前一个和后一个节点通信。但如果某个节点发生故障,在拓扑重新配置之前,整个环就会断开,后面的节点也收不到前面的变更。从系统角度看,这种做法相对脆弱。

星形拓扑有一个中心节点,无论哪个节点发生变更,都会先同步到中心节点,再由中心节点转发出去。除中心节点外,其他节点的复杂度较低,只需管理与中心节点的通信。但如果中心节点故障,而系统没有立即完成故障转移,整个系统的变更同步就会受阻。换句话说,这种做法存在单点故障 (single point of failure) 的风险。

以上讨论体现了分布式系统中常见的取舍。选择更简单的方式 (例如环形拓扑),管理成本会更低,但故障发生时缺少替代路径;选择容错能力更强的方案,管理复杂度也会更高。

备注:本章进一步讨论了多主节点复制中冲突解决的细节,包括 CRDT 等概念。由于篇幅有限,而且我们先前在 本地优先 (local-first) 的软件设计 与 后端系统设计 — 设计实时协同编辑文档系统 (Collaborative Editor) 中讨论过类似概念,这篇导读不再展开。感兴趣的读者可以回顾之前的主题文章,或阅读《DDIA》中这一部分的讲解。

后半篇将进一步介绍无主节点复制 (leaderless replication),这部分内容仅供 E+ 会员 阅读。


加入 E+ 会员方案

如果你觉得这篇分享有帮助,想阅读更深入的内容,欢迎加入 E+ 会员。除了有会员专属的深度文与影片,探讨前后端开发、AI 工程、职业发展,同时有 Discord 社群一同交流与成长。

许多 E+ 会员通过所任职公司的教育训练补助 (E+ 会开立有统编的发票),不用花自己的钱,也能每周通过深度主题文与社群交流,拓展技术视野、加速职业成长。

🧵 如果你想收到最即時的內容更新,可以在 Facebook、Instagram 上追蹤我們