4. 云原生数据库的部署拓扑设计

云原生数据库的部署拓扑不是“把 Pod 分散到几台机器”这么简单。它同时决定了三件事:写入请求沿哪条链路落盘、副本之间如何达成一致、以及单个可用区(AZ)或单台宿主机故障时,业务还能不能继续读写。设计拓扑的本质,是在故障域隔离、一致性级别和延迟成本之间做显式取舍。

一、先定义故障域,再谈副本摆放

故障域是“可能同时失效的一组组件”的边界。云原生环境里常见的故障域从大到小依次是:Region(地域)→ AZ(可用区)→ 物理机/宿主机 → 节点(Node)→ Pod。同一 AZ 内的宿主机通常共享供电、制冷和上联网络,因此“跨宿主机”并不等于“跨故障域”。

一个实用的判断方法是:把拓扑画成“副本—故障域”的映射表,检查任意一个故障域整体失效时,剩余副本数是否仍大于一致性协议要求的多数派(quorum)。以三副本 Raft 为例,多数派为 ⌊3/2⌋+1 = 2。若三个副本分布在 AZ-A、AZ-B、AZ-C,任一 AZ 挂掉后剩 2 个副本,仍可选出 Leader 并继续写入;若三个副本都在 AZ-A,则 AZ-A 故障直接导致集群不可写。这就是故障域隔离效果最直接的量化方式。

二、主从复制拓扑:异步、半同步与组复制

主从复制是最常见的读写分离基础。主库(Primary)接收写入并生成 binlog/WAL,从库(Replica)回放日志。按确认时机不同,可分为:

  • 异步复制:主库提交后立即返回,不等待从库确认。吞吐高、延迟低,但主库故障时可能丢失尚未同步的事务,RPO > 0。
  • 半同步复制:主库至少等待 1 个从库 ACK 后才返回。RPO 显著降低,但写入延迟受最慢从库影响。
  • 组复制 / 多副本一致性协议:基于 Paxos/Raft,多数派确认后提交,支持自动选主,一致性最强,但跨 AZ 部署时每次写入都要跨区往返。

下面这张图给出一个生产级三 AZ 部署拓扑:每个 AZ 放置一个副本,写入经 Leader 同步到 Follower,多数派确认后提交;同时每个 AZ 内部署一个只读副本承接读流量,避免读请求跨区。

三可用区多副本部署拓扑(Raft 多数派 = 2/3) AZ-A(主可用区) Leader 副本 接受写入 · 生成 WAL 只读副本 R1 承接本区读流量 存储卷 PV-A 本地 SSD / 云盘 故障域边界 供电 / 网络 / 制冷 AZ-B(同步副本区) Follower 副本 同步 WAL · 参与投票 只读副本 R2 承接本区读流量 存储卷 PV-B 本地 SSD / 云盘 故障域边界 供电 / 网络 / 制冷 AZ-C(异步副本区) Follower 副本 异步 WAL · 参与投票 只读副本 R3 承接本区读流量 存储卷 PV-C 本地 SSD / 云盘 故障域边界 供电 / 网络 / 制冷 同步复制 异步复制 客户端写入 → Leader(AZ-A)

三、多副本一致性:从“写成功”到“读得到”

副本数量不等于一致性。真正决定一致性的是提交规则和读路径。以 Raft 为例,写入流程是:客户端请求 → Leader 追加日志 → 并行发送 AppendEntries 给 Follower → 收到多数派 ACK → Leader 提交并返回成功。此时若客户端从 Follower 读取,可能读到尚未提交的旧值,这就是“读己之写”问题。

生产上通常采用两种读策略:线性一致读(读请求也走 Leader 或经 ReadIndex 确认当前 Leader 仍为多数派认可)和会话一致性读(客户端携带版本号,从库等待回放到该版本再返回)。前者延迟高但语义强,后者适合读多写少且能容忍短暂延迟的业务。

一个常见的误区是“三副本 = 强一致”。如果三个副本都异步复制,主库提交即返回,那么主库宕机时仍可能丢数据。因此拓扑设计必须把“副本数”和“确认数”分开看:副本数决定容错上限,确认数决定 RPO。

四、跨可用区容灾:RPO 与 RTO 的量化

跨 AZ 部署的核心收益是抵御单 AZ 故障。假设同城三 AZ 之间 RTT 约 1~2 ms,同步复制每次写入增加约 1~2 ms 延迟,这是可接受的;但若跨 Region 同步复制,RTT 可能达到 30~50 ms,写入吞吐会显著下降。因此常见做法是:同城三 AZ 同步复制保 RPO≈0,异地 Region 异步复制保灾难恢复。

下面给出一个可参考的容灾评估表(示例参数,非实测):

故障场景 剩余副本 是否满足多数派 RPO RTO(示例)
单 Pod 故障 2/3 是 0 < 10 s
单宿主机故障 2/3 是 0 < 30 s
单 AZ 故障(AZ-A) 2/3 是 0 30~60 s
双 AZ 故障 1/3 否 取决于异步副本 需人工介入
Region 故障 异地异步副本 — 秒级~分钟级 分钟级

五、落地时的关键检查项

设计完拓扑后,建议用以下清单做一次自检:

  1. 反亲和性:副本 Pod 是否配置了 podAntiAffinity 或拓扑分布约束,确保同一 AZ 内不出现两个投票副本?
  2. 存储绑定:每个副本是否使用独立的 PV,且 PV 的可用区与 Pod 调度区一致?跨区挂载会引入额外延迟甚至失败。
  3. 多数派可写:任意单 AZ 失效后,剩余副本是否仍能选出 Leader?
  4. 读流量本地化:只读副本是否部署在与应用相同的 AZ,避免读请求跨区?
  5. 故障演练:是否定期执行 AZ 级隔离演练,验证 RTO 与预期一致?
拓扑设计没有“最优解”,只有“与业务 SLA 匹配的解”。先明确 RPO/RTO 目标,再反推副本数、确认数和 AZ 分布,比先画图再补一致性要可靠得多。

总结来说,云原生数据库的部署拓扑应围绕三个问题展开:副本放在哪些故障域、写入需要多少副本确认、读请求从哪里返回。把这三件事在拓扑图上显式标注出来,故障域隔离效果就不再是模糊的“高可用”,而是可以逐条验证的工程结论。