Kubernetes 多可用区部署:AI 服务要跨 Zone 但别跨太多 — 方向2

Kubernetes 多可用区部署:AI 服务要跨 Zone 但别跨太多 — 方向2
Kubernetes 多可用区部署AI 服务要跨 Zone 但别跨太多 — 方向2一、两个副本在两个 Zone 里延迟账单谁来付做 AI 推理平台的人迟早会面对一个决策推理服务要不要跨 AZ 部署。直觉上的答案是当然要。既然要做高可用跨可用区是最基本的冗余手段。一个 Zone 的机房故障不会拖垮整个服务。但 GPU 推理场景不是无状态 Web 服务——当你把模型推理的两个副本放到两个 Zone 时多出来的不只是容灾能力还有一份实实在在的延迟账单。以典型的 70B 模型张量并行部署为例如果模型的 4 张 GPU 分布在两台节点上这两台节点分别在不同的可用区。跨 Zone 的网络延迟通常比同 Zone 高出 0.5-2ms。对于普通的 HTTP 请求这个延迟可以忽略。但对于张量并行中频繁发生的 AllReduce 通信——每一层 Transformer 计算后都要同步一次梯度——累积下来的延迟会让单次推理的延迟增加 15-40%。更隐蔽的问题是不是所有情况都需要跨 Zone。如果一个 Region 只有两个可用区你把副本分布到两个 Zone 里每个 Zone 只有一个副本。当其中一个 Zone 故障时剩下的副本承接 100% 的流量——它能不能扛住在 GPU 不足的集群里这个问题的答案往往是扛不住。跨 Zone 是手段不是目的。目的是一台机器挂了流量还能走。二、推理通信模式与容错约束的博弈AI 推理服务的部署模式决定了它对跨 Zone 延迟的敏感程度。不同的并行策略影响截然不同由不同部署方式的通信路径可以得出一个直接的结论单副本模式纯同 Zone延迟最低但没有容灾。一个 Zone 故障即全挂。跨 Zone 镜像每个 Zone 一个完整副本每个副本内部 GPU 都在同一个 Zone不存在跨 Zone 通信。推理延迟不受影响。唯一代价是多占一份 GPU。跨 Zone 张量并行模型跨 Zone 分片最不推荐。每次 AllReduce 都走跨 Zone 链路延迟大幅增加。最佳实践是跨 Zone 镜像而非跨 Zone 分片。用完整的副本来替代跨 Zone 的分片。三、拓扑感知的调度策略当每个 Zone 都部署了完整副本后另一个问题随之而来负载均衡器应优先将请求路由到哪个 Zone 的副本答案取决于你对优先的定义。如果两个 Zone 的处理能力相同就近路由是最优解。但如果 Zone A 有 4 张 A100 而 Zone B 只有 2 张 A800那么 Zone A 应该承载更多流量。以下是一个基于 Kubernetes topology 的调度决策片段// TopologyAwareRouter 基于节点拓扑进行流量分配 type TopologyAwareRouter struct { zones map[string]*ZoneCapacity localZone string healthProbe HealthProbe } type ZoneCapacity struct { Zone string TotalGPU int FreeGPU int Latency time.Duration // 当前Zone到本节点的RTT } func (r *TopologyAwareRouter) Route(zoneHint string) (string, error) { // 第一优先同Zone且GPU充足的副本 if local, ok : r.zones[r.localZone]; ok local.FreeGPU 0 { endpoints : r.getEndpointsInZone(r.localZone) if len(endpoints) 0 { return endpoints[0], nil } } // 第二优先跨Zone但延迟最低的Zone var bestZone string var bestScore float64 for _, z : range r.zones { if z.FreeGPU 0 { continue } // 评分GPU资源权重0.7延迟权重0.3 score : float64(z.FreeGPU)/float64(z.TotalGPU)*0.7 (1.0 - min(1.0, float64(z.Latency)/float64(10*time.Millisecond)))*0.3 if score bestScore { bestScore score bestZone z.Zone } } if bestZone { return , fmt.Errorf(no available endpoint in any zone) } endpoints : r.getEndpointsInZone(bestZone) return endpoints[0], nil }调度策略的设计核心是就近优先跨 Zone 兜底。同 Zone 的副本永远比跨 Zone 的优先级高但跨 Zone 的副本必须作为兜底存在。四、不能什么都跨——边界条件与反模式跨 Zone 部署有几个明确的禁区不要在跨 Zone 场景下做张量并行。如果模型必须跨多张 GPU 做张量并行那这些 GPU 必须放在同一个 Zone。Kubernetes 的topology.kubernetes.io/zone标签可以用于podAffinity约束affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchLabels: model: llama-70b topologyKey: topology.kubernetes.io/zone这确保了一个模型的所有分片被调度到同一个 Zone。不要在两个 Zone 之间做 1:1 副本对等。两个 Zone 各一个副本的布局看似均衡但在单 Zone 故障时剩余副本的 GPU 数量只有总量的一半。如果 GPU 本身已经跑在 70% 利用率上单副本无法承接全部流量。建议的最小拓扑是三 Zone 各一个副本或者两 Zone 其中一 Zone 部署两个副本。不要忽视跨 Zone 的 GPU 型号差异。A100 和 A800 的显存带宽差异在 20% 左右。如果两个 Zone 的 GPU 型号不同负载均衡算法必须感知这种差异。否则请求可能被路由到显存带宽更低的节点导致 P99 延迟波动。适用边界适合每个 Zone 内有完整推理副本的部署模式。不适合需要模型分片跨节点且节点不在同 Zone 的场景。不适合GPU 资源极为稀缺、单 Zone 仅能跑一个副本的环境。五、总结跨可用区部署的正确理解是用空间换容灾但要控制代价。核心规则只有三条第一跨 Zone 镜像不跨 Zone 分片。每个推理副本的所有 GPU 必须在同一个 Zone 内。第二三层调度同 Zone 就近优先、可用容量优先、跨 Zone 兜底。第三副本比例不是 1:1而是确保任意一个 Zone 故障后剩余副本的 GPU 总量仍能接住峰值流量。基础设施不需要漂亮话需要的是在 Zone 真正故障那一刻你部署的副本数量和分布能扛住。