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 为例,写入流程是:客户端请求 → 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 故障 | 异地异步副本 | — | 秒级~分钟级 | 分钟级 |
五、落地时的关键检查项
设计完拓扑后,建议用以下清单做一次自检:
- 反亲和性:副本 Pod 是否配置了
podAntiAffinity或拓扑分布约束,确保同一 AZ 内不出现两个投票副本? - 存储绑定:每个副本是否使用独立的 PV,且 PV 的可用区与 Pod 调度区一致?跨区挂载会引入额外延迟甚至失败。
- 多数派可写:任意单 AZ 失效后,剩余副本是否仍能选出 Leader?
- 读流量本地化:只读副本是否部署在与应用相同的 AZ,避免读请求跨区?
- 故障演练:是否定期执行 AZ 级隔离演练,验证 RTO 与预期一致?
总结来说,云原生数据库的部署拓扑应围绕三个问题展开:副本放在哪些故障域、写入需要多少副本确认、读请求从哪里返回。把这三件事在拓扑图上显式标注出来,故障域隔离效果就不再是模糊的“高可用”,而是可以逐条验证的工程结论。