5.3 地域与可用区

一句话

地域(Region)决定 “数据离用户与监管有多近”,可用区(AZ)决定 “一次机房级故障能带走多少”;两者都是故障域与合规边界的选择,不是 “哪里便宜选哪里”。

三个地理单元,各自决定什么

单元 隔离的是什么 典型 RTT 决定哪个属性
边缘节点(CDN / PoP) 只缓存静态内容与少量动态加速 同城 1–10ms 首屏延迟、回源带宽
可用区 AZ 独立的供电、制冷、网络与机房 同地域跨 AZ 1–2ms 单机房故障的存活率
地域 Region 地理 + 政治边界(数据驻留、法域) 同国跨地域 30–50ms,跨洲 150–250ms 合规、多地域容灾、成本

量级说明:RTT 随距离线性增长,光纤中约 5μs/km(往返 10μs/km),所以 1000 公里天然就是 20ms 起。任何 “跨地域做到 10ms” 的说法都不成立,除非是 “就近接入 + 本地区域内闭环”。

选地域:四条判据,顺序不能换

判据 怎么量 常见错误
① 合规 数据能不能落地该法域、审计要求、出境限制 先选便宜的地域,再找法务 “想办法”
② 延迟 用户分布 × 网络实测(不是 ping 服务器) 用 “机房到机房” 的延迟冒充用户体验
③ 服务可用性 新机型、新特性、新版本在哪个 Region 先上线 架构依赖了只在某一个 Region 才有的能力
④ 成本 单价差异(同规格不同地域可差 10%–20%)+ 出口费 只看单价,不看跨地域流量与专线费

顺序不能换的原因:合规是硬边界(不可谈),延迟是体验底线,服务可用性是架构约束,只有成本可以商量。反过来按 “成本优先” 选地域,后面三项都会以返工的形式补回来。

AZ:故障域,不是 “机架”

  • AZ 之间物理独立:独立供电、制冷、网络出口,所以 “一个 AZ 全灭” 不会连带另一个。
  • 但 AZ 之间网络互联,跨 AZ 调用有 1–2ms 的 RTT 与流量费(量级每 GB 一分钱上下,以价目表为准)。
  • 因此 “把三副本放三个 AZ” 换来的是 “挂一个 AZ 仍有两副本”;而 “三副本放同一个 AZ 的三个机架”,挂一个 AZ 等于三副本全灭——这是最常见的假高可用。

多数地域提供 3 个上下(部分 2 个或 5 个以上,以官方文档为准)。3 AZ 的最优用途是放 quorum 副本:3 副本分布在 3 个 AZ,任意 1 个 AZ 故障仍满足多数派,W + R > N 的相交条件不变(推导见 21.2 Quorum 与 W + R > N 的证明)。2 个 AZ 则必须做 “1 + 1” 的副本布局,此时挂一个 AZ 就只剩 1 副本,多数派不成立——双 AZ 不是缩小的三 AZ,而是另一种取舍。

放置策略:让副本真的分开了

手段 保证什么 什么时候会失效
反亲和(anti-affinity) 同角色的 Pod 不落在同一节点/AZ 资源不足时调度器 “软失败”,照样挤在一起
拓扑分布约束(topologySpreadConstraints) 按 AZ/节点均分副本数 maxSkew 设太大,等于没约束
云厂商的分布组(spread placement group) 实例分散到不同物理机 只覆盖计算,不覆盖存储与网络
手工指定子网 明确每个实例在哪个 AZ 扩容模板没同步,新实例又回到单 AZ

四种手段的共同前提是可验证:部署完抽查一次实际分布(kubectl get pod -o wide 看节点所属 AZ、或云控制台的分布视图)。没有抽查的 “已做多 AZ”,通常只是 “填了参数”。

多 AZ 不等于多活:上限由共享依赖决定

理论上,两个独立 AZ 各 99.9% 可用性,组合可用性约 1 − (1 − 0.999)² ≈ 99.9999%。现实中做不到,因为共同依赖才是瓶颈:

共同依赖 它挂了会怎样 缓解
单主数据库(写在 AZ-A) AZ-A 挂 = 写入全停 跨 AZ 同步副本 + 自动切主(RTO 决定可用性)
负载均衡 / DNS / 证书 全局入口挂 = 全部不可用 入口本身做多 AZ + 多供应商
控制面(K8s API、IAM、配额服务) 扩不了容、验不了权 提前缓存凭证、预留容量
同一条专线 / 同一个 NAT 网络单点 双专线、每 AZ 独立 NAT
同一个人值班 人的单点 on-call 轮转 + runbook
部署形态 覆盖的故障域 年停机量级(目标) 成本倍数
单 AZ 无 99.9% → 约 8.8 小时 1×
多 AZ(同地域) 机房级 99.95%–99.99% 1.2–2×
多地域(双活) 地域级 99.99%+ 2× 起,含数据复制
单元化多活 地域 + 租户级 99.995%+ 3× 起,含流量调度

这张表的用法是先定目标再选形态,而不是 “能多活就多活”:年停机 8.8 小时可接受时,多 AZ 的 1.2 倍成本已经足够,多地域是纯浪费。灾备目标(RTO / RPO)与拓扑的完整推导见 36.1 RTO / RPO 与 36.4 两地三中心与多活。

跨 AZ 的账:延迟与流量费要一起算

一个请求如果经过 4 个服务、每个服务跨 AZ 一次,就多 4 段跨 AZ 往返:RTT 增加约 4–8ms,流量费按进出两次计。两种常见放大:

  • 聊天式调用:一次业务请求拆成 20 次 RPC,全部跨 AZ,延迟与流量费同时翻倍。修法是同 AZ 优先路由(拓扑感知负载均衡)+ 减少调用次数。
  • 缓存与数据库的跨 AZ 读:为了 “均匀” 把读也打到跨 AZ 副本,代价是每次读 1–2ms。修法是读写都在本地 AZ 闭环,跨 AZ 只做复制。

流量费的具体结构见 5.6 云成本结构:跨 AZ 与出口流量是账单里最容易漏的两项。

决策表

你的情况 选择
单机可承受停机,成本敏感 单 AZ,但把备份放另一个 AZ
有状态主库 + 要求 99.95% 多 AZ + 同步副本 + 自动切主(演练过)
用户只在一个城市、延迟敏感 单地域多 AZ + 边缘缓存,不跨地域
用户跨洲、有数据驻留要求 多地域,每地域数据闭环,只同步脱敏聚合结果
有监管要求 “境内存储” 地域选择先过合规,再谈成本(见 5.2 部署模型:公有 / 私有 / 混合)

代码:查清 AZ 与实例的实际可用性

# 1) 这个地域有哪些可用区(注意:AZ 名字与物理机房是“每账号随机映射”的)
aws ec2 describe-availability-zones --region ap-southeast-1 \
  --query 'AvailabilityZones[].[ZoneName,State,ZoneId]' --output table

# 2) 某个实例规格在哪些 AZ 有货(“AZ 存在 ≠ 该规格能买到”)
aws ec2 describe-instance-type-offerings --region ap-southeast-1 \
  --location-type availability-zone \
  --filters Name=instance-type,Values=m6i.xlarge \
  --query 'InstanceTypeOfferings[].[Location,InstanceType]' --output table

# 3) 跨 AZ 的实际延迟(两台机器互 ping,看 P50/P99)
ping -c 100 <peer-ip-in-another-az> | tail -2
# Terraform:把“多 AZ”写成“每个 AZ 一个子网”,而不是一个子网挂所有实例
resource "aws_subnet" "app" {
  for_each          = toset(data.aws_availability_zones.available.names)
  availability_zone = each.key
  cidr_block        = cidrsubnet(var.vpc_cidr, 8, index(data.aws_availability_zones.available.names, each.key))
}

反模式

反模式 后果
三副本放同一 AZ 的三个机架 以为做了高可用,一次 AZ 故障全灭
双 AZ 却按 “3 副本多数派” 设计 挂一个 AZ 只剩 1 副本,写不进去
多 AZ 但数据库单主 计算层冗余,故障时写入全停
为了省跨 AZ 流量费把副本挤在一起 省下的钱远小于一次故障的损失
只填了反亲和参数,没抽查分布 资源紧张时调度器静默合并 Pod
选地域只看单价 合规返工、延迟不达标、专线费反超
认为 “跨地域可以做到 10ms” 物理定律不配合,方案从前提就是错的

三条铁律

🔑 AZ 是故障域,机架不是:只把副本分到不同机器,等于没分。

🔑 多 AZ 的可用性上限由共同依赖决定,不由 AZ 数量决定;先列共享单点,再谈拓扑。

🔑 先定年停机目标(几个 9),再选单 AZ / 多 AZ / 多地域;反过来选,成本一定花在看不见的地方。

自检

Q1 一个服务部署了 3 个副本,分在同一 AZ 的 3 台不同物理机上。能扛住 AZ 故障吗?

▸ 答案:不能。AZ 故障会同时带走该 AZ 内所有机器,3 个副本 100% 丢失。AZ 内的反亲和只解决 “单机 / 单机架” 故障;要扛 AZ 故障,副本必须分布到 ≥ 2 个 AZ,并且多数派布局要匹配(3 副本跨 3 AZ 时,挂 1 个 AZ 仍满足多数派)。

Q2 两个 AZ 各 99.9%,为什么实际做到 99.99% 都很难?

▸ 答案:因为 1 − (1 − 0.999)² 的 99.9999% 假设了故障完全独立,而真实系统共享一堆依赖:单主数据库、DNS、负载均衡、IAM、专线、甚至同一个值班的人。只要这些共享依赖里的任意一个挂掉,两个 AZ 一起不可用。所以多 AZ 的可用性上限取决于 “共同依赖有几个、各自多可靠”,不取决于 AZ 个数。

Q3 用户分布在华东与华南,是否应该直接上 “两地双活”?

▸ 答案:先算账:华东到华南 RTT 约 30ms,单地域多 AZ + 边缘缓存通常已能把首屏压到可接受范围。两地双活要解决的是数据双写与冲突(写入延迟、跨地域一致性、切流演练),成本 2 倍起。判断标准是 “RTO 目标是否要求地域级故障也能续命”,而不是 “用户分在两个地方”。若只是延迟,靠 CDN + 就近接入更便宜。

Q4 跨 AZ 架构上线后,账单里多出一笔 “区域间数据传输费”,怎么解释给老板?

▸ 答案:这是跨 AZ 的必然成本:副本复制、跨 AZ 调用、跨 AZ 备份都会产生流量费(量级每 GB 一分钱上下)。取舍是明确的:花这笔钱买 “单 AZ 故障不丢服务”。要压低它,靠三件事——同 AZ 优先路由、减少跨 AZ 调用次数、把非关键流量(日志、分析)留在本 AZ。

Q5 云厂商在 B 地域上线了新机型,团队想整体迁过去。该考虑哪三件事?

▸ 答案:① 合规(数据驻留与审计口径是否允许换地域);② 迁移成本(跨地域数据搬迁的时长与流量费,见 5.7 云厂商锁定与迁移 的量化方法);③ 延迟与用户分布(新地域离用户更近还是更远)。只为 “新机型便宜 10%” 迁移,通常会被搬迁成本与业务中断风险吃掉。

跨篇相关:服务模型决定 “地域里你能控制到哪一层”,见 5.1 服务模型:IaaS / PaaS / FaaS;部署形态与合规边界见 5.2 部署模型:公有 / 私有 / 混合;容灾目标与拓扑见 36.1 RTO / RPO、36.4 两地三中心与多活;多数派放置见 21.2 Quorum 与 W + R > N 的证明;跨 AZ 与出口流量的计费结构见 5.6 云成本结构;跨地域搬迁的代价见 5.7 云厂商锁定与迁移。