复制:主从、多主、无主

发布时间:2026/8/30 15:34:51
复制:主从、多主、无主 每台机器只有「部分的真相」。复制是把同一份数据放到多台机器上让系统在单机挂掉时还能继续服务。为什么需要复制单机有物理上限。数据量可能超过单机磁盘请求量可能超过单机 CPU还有机器故障、机房断电这些不可抗力。复制把数据拷贝到多台机器用冗余换可用性。这是分布式系统最原始的动力——如果一台机器够用后面的一切都不用折腾。但复制一旦做起来问题就跟着来了多台机器上的同一份数据写入该交给谁处理主从复制最简单的起点直觉做法有一个节点说了算。指定一个主节点所有写入都走它从节点只负责同步数据和承接读请求。这是最常见的方式。MySQL 的 binlog 复制、PostgreSQL 的流复制、Redis 的主从都这么做。架构简单读可以水平扩展写走主节点不会冲突。问题也明显。写入瓶颈全在主节点上——从节点再多写吞吐也卡在主节点一台机器。主节点挂了更麻烦要切主从节点里选一个升级。这个过程有窗口窗口期内系统不可写。多主复制解写入瓶颈主从的写入瓶颈很自然引出多主让多个节点都能写。多主复制常见于多数据中心场景。每个数据中心有一个主节点负责本地写入异步复制到其他数据中心。DynamoDB 的全局表、CouchDB 的同步都是这个思路。但多个节点同时写同一份数据冲突就来了。两个数据中心同时改了同一条记录谁说了算多主复制必须处理冲突——要么用最后写入者胜LWW靠时间戳要么用更复杂的冲突解决逻辑CRDT。无主复制干脆不指定主多主的冲突解决是额外复杂度。再往前走一步干脆不指定主节点所有节点平等客户端直接向多个节点读写。这个思路来自 Amazon 的 Dynamo 论文。Cassandra、Riak 都采用了无主设计。客户端写数据时向多个节点发请求读数据时也向多个节点发请求通过 quorum 机制保证一致性。典型配置是W R N写需要 W 个节点确认读需要 R 个节点响应只要 W R 大于总节点数 N读请求一定能看到最新的写。这个不等式很简单但效果很好——你不需要知道哪个节点是主只需要数确认数。无主的好处是节点平等没有切主问题故障时自然降级。代价是实现复杂冲突得在读路径上解决读修复、反熵这些机制要补上。复制延迟不管选哪种复制从节点追上主节点需要时间。这个延迟带来一类读一致性问题。你刚写了数据读到从节点发现数据没了——读己之写。你连续读了两次第二次发现数据退回去了——单调读失败。这些问题不只在主从中出现多主和无主一样要面对只要存在异步复制就有这个窗口。同步还是异步同步复制等所有从节点确认再返回强一致但慢异步复制主节点写完就返回快但可能丢数据。主从、多主、无主都有这个取舍只是具体实现方式不同。这是分布式系统里最经典的权衡没选同步就要接受丢数据的可能选了同步就要接受延迟。故障恢复节点挂了再加回来怎么追上错过的数据。主从里靠重放日志无主里靠读修复和 hinted handoff。每种模式的恢复机制不同但问题是共通的。小结复制是让数据在空间上分布的手段。主从最简单但写入瓶颈和切主是代价多主解了写入瓶颈但引入冲突解决无主最灵活节点平等、故障自然降级但实现复杂度最高。三个方案不是互斥的——实际系统里经常混着用比如主从架构配 quorum 读写。无论选哪种复制延迟和一致性的取舍是绕不开的。这是分布式系统在空间维度上的核心矛盾想用复制换可用性就得接受数据不会立刻一致。