本页目录

复制策略

让多台机器持有同一份数据的拷贝——怎么保证它们一致?单 leader 简单但写瓶颈,多 leader 允许异地写但冲突多,leaderless 牺牲一致性换可用性。三种策略在一致性、延迟和容错之间的取舍,是分布式存储的第一次分岔。

单 Leader (Primary-Backup / Master-Slave)

所有写操作必须经过 leader。Leader 将写持久化到自己的 WAL,然后通过复制(同步或异步)传播到 followers。

Client → Leader:   write(x=1)
Leader:             append to WAL → fsync → 返回 OK to client (if synchronous)
                    → 异步 or 同步 复制到 followers
Followers:          收到 new entries → apply to local state
Client → Follower:  read(x) → 可能返回旧值 (replication lag)

复制方式

同步复制⁠:Leader 等至少一个 follower 确认后才返回 client。保证至少一个 follower 有最新数据——如果 leader crash,该 follower 可以接替且不丢数据。代价:写延迟 = 两节点中最慢的 fsync 时间。

异步复制⁠:Leader 不等 follower 确认。写的延迟最小,但 leader crash 时未确认的 writes 会丢失(RPO > 0)。

半同步 (MySQL semisync):等至少一个 follower 确认,但不等所有。兼顾 durability 和延迟。

Read-Your-Writes 问题

异步复制下 client 写 leader 后立即从 follower 读——可能读不到刚刚写的。解决方案:1) 强制读 leader for writes 有因果关系的后续 reads; 2) follower 返回当前 apply 的 log position,client 下一次 read 指定 token → follower 等到 >= token。

多 Leader (Multi-Master)

所有节点都可接受写请求,异步复制到其他节点。优势:写入延迟低(不经过 leader)、容忍网络分区时仍可写(各分区内节点可独立接受写入)。代价:写冲突。

Node A: write(x=1) → 异步复制 → Node B
Node B: write(x=2) → 异步复制 → Node A
→ 冲突! A 看到 (x=1 → x=2), B 看到 (x=2 → x=1)
→ 需要冲突解决 (LWW, 版本向量, CRDT — 见 03-02)

Leaderless (Dynamo-style)

无 leader 角色——写向多个节点,读也从多个节点,通过 quorum 保证一致性。

Dynamo (Amazon 2007) 的模型:

  • N: 数据被复制到的节点总数
  • W: 写需要 W 个节点确认(包括 coordinator)
  • R: 读需要 R 个节点参与(包括 coordinator)
  • 如果 R + W > N: 读写 quorum 必有重叠 → 至少一个节点有最新数据(保证线性一致性)
Coordinator (任意的——client 可以直接或通过 load balancer 到任意节点):
  write(key, value, context):
    1. 生成 vector clock version
    2. 并发发送到 N 个 replicas
    3. 等 W-1 个确认 (加上自己 = W)
    4. 返回 OK to client

  read(key):
    1. 并发从 N 个 replicas 读 (发请求)
    2. 等 R 个回复
    3. 选择 version 最新的 value (by vector clock comparison)
    4. 如果发现 conflict (versions 不可比较) → 返回所有 conflicting siblings 给 client (应用层解决)
    5. 异步修复 (read repair): coordinator 把最新版本写回落后节点

Hinted Handoff

如果 coordinator 无法联系到所有 N 个 replicas,它把数据暂时存在 coordinator 本地的"hint"中。当目标 replica 恢复时,coordinator 转发 hint。确保在节点故障时系统继续可用。

Sloppy Quorum vs Strict Quorum

严格 quorum 要求写入 N 个"目标 replicas"中的至少 W 个。Sloppy quorum: 只要总共有 W 个节点确认(可以是非目标节点接手),就算可用——在节点故障时提高可用性,但可能违反 R+W>N 的一致性保证。

参考

  • 论文⁠: "Dynamo: Amazon's Highly Available Key-value Store" (2007)
  • Cassandra: cassandra.apache.org (Dynamo + BigTable 的混合体)
  • MySQL: Group Replication (基于 Paxos, 单 leader 变体)

Keywords: leader-based replication, multi-leader, leaderless, quorum, Dynamo, hinted handoff, read repair, sloppy quorum