2. 故障域概念:故障域定义、常见故障域类型与 etcd 集群拓扑的关系

2.1 故障域定义

故障域(Fault Domain)是分布式系统中一组共享单一故障点的物理或逻辑资源集合。当该故障点失效时,集合内的所有组件将同时失去服务能力。故障域的核心价值在于:通过将冗余副本部署在不同的故障域中,系统可以在单个故障域失效时仍保持整体可用性。

关键原则:etcd 集群的高可用性直接取决于其成员是否分布在相互独立的故障域中。如果集群的所有成员位于同一个故障域,则该故障域的任何故障都会导致整个集群不可用。

2.2 常见故障域类型

在数据中心和云环境中,故障域通常按物理隔离程度从低到高分为以下层级:

故障域类型 隔离粒度 典型故障范围 恢复时间目标(RTO)参考
机架(Rack) 单机柜 电源故障、交换机故障、机架级网络中断 分钟级
可用区(AZ) 独立数据中心或楼层 区域电力中断、制冷失效、骨干网络故障 分钟~小时级
区域(Region) 地理隔离区域 自然灾害、大规模电力事故、政治事件 小时~天级

2.3 故障域与 etcd 集群拓扑的关系

etcd 使用 Raft 共识算法,要求集群中多数成员(quorum)存活才能对外提供服务。故障域划分直接影响 quorum 的存活概率。以下关系图展示了不同故障域层级下的 etcd 部署拓扑:

故障域层级与 etcd 集群拓扑关系 机架级故障域 etcd-1 etcd-2 etcd-3 所有成员在同一机架 单点故障导致集群不可用 ❌ 不推荐 可用区级故障域 etcd-1 AZ-A etcd-2 AZ-B etcd-3 AZ-C 每个成员在不同可用区 单 AZ 故障不影响 quorum ✅ 推荐(3 AZ 部署) 区域级故障域 etcd-1 Region-1 etcd-2 Region-2 etcd-3 Region-3 跨区域部署 网络延迟高,不推荐 ⚠️ 谨慎使用 故障域与 etcd 集群拓扑的关键关系 1. quorum 存活条件:etcd 集群需要多数成员存活(n/2+1)。3 节点集群最多容忍 1 个故障域失效。 2. 故障域隔离度:故障域隔离越彻底,集群抗风险能力越强。机架级 < AZ 级 < Region 级。 3. 网络延迟代价:跨故障域部署会增加 Raft 心跳延迟。AZ 内延迟通常 < 2ms,跨 Region 可达 50-200ms。 4. 推荐实践:生产环境 etcd 集群应跨 3 个可用区(AZ)部署,每个 AZ 部署 1 个成员。 5. 资源变更影响:当集群成员因资源变更(扩缩容、迁移)而改变故障域分布时,需重新评估 quorum 存活能力。 6. 避免对称故障:不要将 etcd 成员部署在共享同一电源、网络交换机或物理主机的故障域内。

2.4 故障域划分对 etcd 一致性的影响

故障域划分不仅影响可用性,还直接影响 etcd 的一致性保证。以下是不同故障域场景下的一致性风险分析:

故障域场景 一致性风险 说明
所有成员在同一机架 高 机架级故障(如交换机断电)导致所有成员同时失联,集群完全不可用,无法保证一致性。
跨 2 个 AZ 部署(3 节点) 中 若一个 AZ 故障,剩余 2 个节点仍可形成 quorum;但若故障 AZ 包含 leader,需重新选举,存在短暂不可用窗口。
跨 3 个 AZ 部署(3 节点) 低 任意一个 AZ 故障,剩余 2 个节点仍可形成 quorum;leader 切换后一致性不受影响。
跨 Region 部署(3 节点) 极高 网络分区可能导致 Raft 选举频繁失败,脑裂风险增加,一致性保证被严重削弱。

重要警告:etcd 官方明确不建议跨 Region 部署同一集群。跨 Region 的高延迟和网络分区风险会破坏 Raft 协议的正常运行,导致频繁的 leader 选举和性能急剧下降。如果需要跨 Region 容灾,应使用 etcd 的 镜像(Mirror) 或 网关(Gateway) 方案,而非直接扩展集群。

2.5 故障域划分的最佳实践

  1. 最小化共享故障点:确保 etcd 集群的每个成员运行在独立的物理机、独立的网络交换机和独立的电源域中。
  2. AZ 优先原则:在云环境中,优先选择跨 3 个可用区部署,每个 AZ 部署一个 etcd 成员。
  3. 避免偶数节点:故障域数量应为奇数(3、5、7),以确保在部分故障域失效时仍能形成 quorum。
  4. 资源变更复核:每次集群扩缩容或成员迁移后,必须重新检查故障域分布是否仍然满足 quorum 存活条件。
  5. 监控故障域健康:建立故障域级别的监控告警,当某个故障域内的 etcd 成员出现异常时,及时触发人工复核流程。

SRE 实战提示:在 Kubernetes 环境中,可以通过 topology.kubernetes.io/zone 标签将 etcd Pod 调度到不同可用区。使用 PodAntiAffinity 规则确保同一 etcd 集群的成员不会调度到同一节点或同一可用区。