AWS 已告知客户:对于仅托管在阿联酋 mec1-az2 可用区中的资源和数据,以及仅存在于巴林区域中的资源和数据,AWS 无法完成恢复。AWS 表示,巴林的损坏跨越了多个可用区,超出了区域级和 Multi-AZ 服务原本设计承受的范围。
这件事提醒团队重新区分三个经常被混在一起的概念:高可用、备份和灾难恢复。Multi-AZ 能降低单个可用区故障的影响,但当多个可用区遭遇相关性破坏时,真正决定数据能否回来的是:事故发生前,是否已经把可恢复副本放到了另一个故障域。
Multi-AZ 解决的不是所有故障
典型的 Multi-AZ 架构会把计算节点、数据库副本或负载均衡能力分散到同一区域的多个可用区。它主要应对的是单个数据中心或单个可用区失效,例如电力、网络和硬件故障。
区域内多个可用区仍然存在一些共同依赖。极端事件一旦同时影响多个可用区,以下配置就可能失去作用:
- 应用跨两个或三个可用区部署,但数据库备份仍只保存在原区域。
- 数据库启用了 Multi-AZ,却没有跨区域快照或日志复制。
- 对象存储启用了版本控制,但副本仍位于同一区域。
- 业务数据已经跨区域复制,但 KMS 密钥、IAM 恢复角色、容器镜像或 Terraform 状态没有同步。
- 灾备区域有基础设施模板,却从未验证过能否在目标 RTO 内恢复数据并接管流量。
因此,Multi-AZ 更准确的定位是区域内高可用机制。跨区域灾备则需要另一套明确的复制、隔离、恢复和切流设计。
先找出“唯一副本”与单可用区依赖
事故发生后再复制数据通常已经太晚。团队可以先盘点资源是否集中在某个可用区,以及哪些数据只有区域内副本。
下面的脚本可用于检查指定 AWS 区域和可用区 ID 中的 EC2、EBS、子网与 RDS 实例。运行前需要安装 AWS CLI 和 jq,并配置具有只读权限的凭证。
需要注意,类似 me-central-1a 的可用区名称可能因 AWS 账户而异,因此盘点时应优先使用 mec1-az2 这样的可用区 ID;脚本会先把 ID 转换为当前账户中的可用区名称。
#!/usr/bin/env bash
set -euo pipefail
REGION="${1:-me-central-1}"
ZONE_ID="${2:-mec1-az2}"
command -v aws >/dev/null || { echo "aws CLI is required" >&2; exit 1; }
command -v jq >/dev/null || { echo "jq is required" >&2; exit 1; }
ZONE_NAME=$(aws ec2 describe-availability-zones \
--region "$REGION" \
--all-availability-zones \
--query "AvailabilityZones[?ZoneId=='${ZONE_ID}'].ZoneName | [0]" \
--output text)
if [[ -z "$ZONE_NAME" || "$ZONE_NAME" == "None" ]]; then
echo "Zone ID $ZONE_ID was not found in region $REGION" >&2
exit 1
fi
echo "Inspecting region=$REGION zone_id=$ZONE_ID zone_name=$ZONE_NAME"
echo "--- EC2 instances ---"
aws ec2 describe-instances \
--region "$REGION" \
--filters "Name=availability-zone,Values=$ZONE_NAME" \
--query 'Reservations[].Instances[].{Id:InstanceId,State:State.Name,PrivateIp:PrivateIpAddress}' \
--output table
echo "--- EBS volumes ---"
aws ec2 describe-volumes \
--region "$REGION" \
--filters "Name=availability-zone,Values=$ZONE_NAME" \
--query 'Volumes[].{Id:VolumeId,State:State,Encrypted:Encrypted,SizeGiB:Size,Snapshot:SnapshotId}' \
--output table
echo "--- Subnets ---"
aws ec2 describe-subnets \
--region "$REGION" \
--filters "Name=availability-zone,Values=$ZONE_NAME" \
--query 'Subnets[].{Id:SubnetId,Vpc:VpcId,CIDR:CidrBlock,FreeIPs:AvailableIpAddressCount}' \
--output table
echo "--- RDS instances whose primary AZ is here ---"
aws rds describe-db-instances \
--region "$REGION" \
--output json | jq --arg az "$ZONE_NAME" '
.DBInstances[]
| select(.AvailabilityZone == $az)
| {
id: .DBInstanceIdentifier,
engine: .Engine,
multi_az: .MultiAZ,
primary_az: .AvailabilityZone,
backup_retention_days: .BackupRetentionPeriod
}'
例如可以保存为 audit-az.sh,然后执行:
chmod +x audit-az.sh
./audit-az.sh me-central-1 mec1-az2
这只是起点,并不是完整的灾备审计。脚本没有覆盖 ElastiCache、OpenSearch、EKS 持久卷、S3、EFS、托管消息队列和第三方 SaaS,也无法仅通过 RDS 的 MultiAZ 字段证明备用副本位于何处。对于巴林这种区域内多个可用区同时受损的场景,还需要按整个区域检查数据副本,而不能只过滤一个可用区。
跨区域副本必须在事故前准备好
对于 EBS 快照,可以在源区域仍可访问时把快照复制到独立区域。下面的命令可直接改造使用;请替换快照 ID、目标区域和目标区域中的 KMS 密钥 ARN。
#!/usr/bin/env bash
set -euo pipefail
SOURCE_REGION="me-central-1"
DESTINATION_REGION="eu-west-1"
SOURCE_SNAPSHOT_ID="snap-0123456789abcdef0"
DESTINATION_KMS_KEY_ARN="arn:aws:kms:eu-west-1:123456789012:key/11111111-2222-3333-4444-555555555555"
COPY_ID=$(aws ec2 copy-snapshot \
--source-region "$SOURCE_REGION" \
--source-snapshot-id "$SOURCE_SNAPSHOT_ID" \
--destination-region "$DESTINATION_REGION" \
--encrypted \
--kms-key-id "$DESTINATION_KMS_KEY_ARN" \
--description "Cross-region DR copy of $SOURCE_SNAPSHOT_ID" \
--query SnapshotId \
--output text)
echo "Created destination snapshot: $COPY_ID"
aws ec2 wait snapshot-completed \
--region "$DESTINATION_REGION" \
--snapshot-ids "$COPY_ID"
echo "Snapshot $COPY_ID is ready in $DESTINATION_REGION"
这段命令有一个关键前提:源快照在复制时仍然可读,相关 KMS 权限也仍然有效。它不能在源数据已经不可访问之后“补做灾备”。生产环境还应把复制变成定时策略,并增加以下保护:
- 把副本放入不同区域,必要时再放入独立 AWS 账户。
- 为目标区域预先配置 KMS 密钥、恢复角色和最小权限策略。
- 对数据库使用适合其一致性要求的备份方式,而不是只复制崩溃一致的磁盘快照。
- 为备份设置保留期、不可变策略和删除保护,避免误删或凭证泄露同时摧毁主数据与备份。
- 监控复制延迟,因为复制延迟直接决定实际 RPO。
- 定期从副本创建新环境,验证数据能被解密、加载和提供服务。
灾备的验收标准应该是“能恢复”
“已经启用 Multi-AZ”或“控制台里能看到备份”都不是最终结果。更有用的验收方式,是让团队回答一组可以测试的问题:
- 如果整个主区域不可用,最近一份区域外副本是什么时间生成的?
- 目标区域是否有足够的配额、网络、镜像、密钥和权限?
- 基础设施能否通过代码重建,还是依赖控制台中的手工配置?
- DNS、证书、身份系统和外部 API 是否也能从灾备区域访问?
- 恢复后的数据完整性如何校验,谁有权决定切流和回切?
- 最近一次完整恢复演练用了多久,是否达到约定的 RTO 与 RPO?
跨区域复制会增加成本、运维复杂度和数据一致性处理难度;跨云方案还会引入 API 差异、网络费用和更复杂的身份体系。并非每个系统都需要主动—主动架构,但只要业务无法接受永久数据丢失,就不应让唯一可恢复副本停留在同一个故障域中。
这次事件最值得带走的结论不是“多部署一个可用区”,而是明确架构的承受边界:Multi-AZ 用于减少区域内局部故障的影响;真正面对区域级灾难的,是提前存在、独立受控并经过恢复演练的跨区域副本。