什么是异地多活
一句话:在多个地理区域同时部署业务系统,每个区域都能独立、完整地对外提供服务(可读可写、能扛流量)。一个区域挂了,其他区域能立刻顶上,用户几乎无感知。
异地
地理位置足够远(通常跨城市、>100km),使它们不会同时遭遇同一灾害:光缆被挖断、断电、地震、洪水。
多
至少 2 个及以上区域同时运行。区别于"主 + 备份"的单点结构,多活没有永远闲置的备。
活
每个单元都是"活的"——平时就在接流量,而非出事才启用。这是和冷备/热备最本质的区别。
一个主、一个备
平时只有主机房接流量,备机房空转等故障。主机房宕机后,需手动/半自动切换,期间业务中断(RTO 分钟~小时级)。
多区域同时接流量
每个区域都正常服务用户。某区域故障,流量被路由到其他区域,用户几乎无感知,RTO 趋近于秒级。
为什么需要异地多活
单机房再强,也扛不住"物理世界"的意外。多活是把"业务连续性"从概率事件变成确定性能力。
容灾兜底
机房断电、光缆被挖断、自然灾害……单机房是单点。多活让"一个城市没了"也不影响全局。
就近接入降延迟
北京用户访问北京region,深圳用户访问深圳region,跨城几十~上百ms的延迟被省掉,体验更好。
突破单机房上限
单机房电力、机柜、配额、带宽都有天花板。多活横向铺开,总容量不再是瓶颈。
合规与属地化
某些数据法规要求"数据不出省/国"。多活可在合规地域部署对应单元,满足数据驻留要求。
容易混淆的概念辨析
同城双活、异地多活、冷备、热备、两地三中心、单元化……这些词经常被混用,先理清边界。
| 概念 | 距离 | 备是否接流量 | 故障时 | 典型 RTO |
|---|---|---|---|---|
| 冷备 | 任意 | 否(停机待命) | 需启动+恢复,中断久 | 小时级 |
| 热备 | 同城居多 | 数据同步但不接流量 | 切换较快,仍有中断 | 分钟级 |
| 同城双活 | <50km | 是 | 几乎无缝 | 秒级 |
| 异地多活 | >100km(跨城) | 是 | 几乎无缝 | 秒级 |
| 两地三中心 | 同城+异地 | 同城活/异地备或活 | 同城优先,异地兜底 | 秒~分钟 |
单元化(Cell)
按用户维度(如 user_id 哈希)把业务切成自包含的小单元,每个单元部署在固定 region,请求在该单元内闭环。这是多活最主流的落地姿势。
RTO / RPO
RTO=恢复时间目标(中断多久);RPO=恢复点目标(最多丢多少数据)。多活追求 RTO 秒级、RPO 接近 0。
典型架构长什么样
多个 region 各自有完整链路(接入→应用→存储),GSLB 做 DNS 级分流,region 之间通过数据同步保持最终一致。
每个 Region 都是一套完整的接入+应用+存储,平时都在接流量;红色虚线表示 region 之间的异步数据同步。
流量调度
GSLB(基于 DNS 的全局负载均衡)按用户地理位置/运营商把请求导到最近 region;细粒度可结合 HTTPDNS、应用层路由。
数据同步
MySQL 跨城主从/双向复制、Redis 跨城同步、消息队列跨城投递。一般异步、最终一致,避免跨城强一致拖慢主链路。
单元化路由
按 user_id 把用户固定到某 region(单元),其读写尽量在本 region 闭环,跨城同步只发生在必要场景。
最难的一环:数据一致性
多活最头疼的是"多个 region 都能写,怎么不冲突、不丢数据"。核心矛盾:跨城网络延迟 vs 一致性要求。
| 方案 | 思路 | 一致性 | 适用 |
|---|---|---|---|
| 全局单写 | 某数据只在固定 region 写,其他 region 异步复制只读 | 最终一致 | 全局配置、库存中心 |
| 单元化单写 | 按 user_id 分片,每片只在自己 region 写 | 单元内强一致、跨单元最终一致 | 交易、账户(最主流) |
| 多写 + 冲突解决 | 各 region 可写,靠版本号/CRDT/业务规则合并 | 最终一致 | 可合并的弱序数据 |
| 跨城同步复制 | 写需等异地确认(半同步) | 接近强一致 | 金融强一致场景(牺牲延迟) |
容灾与切换
多活不是"部署完就高枕无忧",真正考验的是故障时的发现、决策、切流能力。
故障检测
健康探针、拨测、黄金指标(延迟/错误率/QPS)异常告警。误判会导致"误切流",需防抖。
流量切流
调整 GSLB 权重/解析,把故障 region 的流量逐步导走。支持按比例灰度切,避免雪崩。
脑裂防护
网络分区时两 region 都以为对方挂了、各自"升主"导致双写冲突。需租约/仲裁(quorum)机制防脑裂。
常态化演练
红蓝对抗、混沌工程注入机房故障,验证切换链路真的有效。不演练的多活=纸面多活。
单元化设计实战
单元化是异地多活最主流、也最落地的实现方式。下面用一个路由演示直观感受。
按维度切分
用 user_id(或租户id、订单id)做分片键。同一用户的全部数据落在同一单元,读写闭环。
全局 vs 单元数据
单元数据(用户资料、订单)本地闭环;全局数据(商品目录、汇率)走单写+广播。
跨单元交互
转账给异地用户 = 跨单元。需异步对账/补偿(Saga、消息最终一致),不能卡住主链路。
难点与代价(避坑)
异地多活很香,但很贵也很难。先想清楚值不值得,再动手。
成本翻倍
每多一个活 region,就是一整套计算+存储+带宽。平时都在跑,没有"备机省钱"这回事。
一致性复杂
冲突检测、补偿、对账、幂等……分布式一致性工程量是多活的主要技术债。
业务改造大
要去状态、要分片、要幂等、要梳理全局/单元数据。老系统改造成本可能超过重建。
运维门槛高
跨城网络、时钟漂移、切流决策、脑裂处理……对团队 SRE 能力要求极高。
总结与决策清单
一句话记住:异地多活 = 多个城市都跑着完整业务,平时就接流量,挂一个其他顶上。
| 你的处境 | 建议 |
|---|---|
| 单机房、能接受分钟级中断 | 主备 + 定期切换演练即可,不必上多活 |
| 核心业务、RTO 要求秒级、怕城市级灾难 | 上异地多活,优先单元化 |
| 用户分散全国、延迟敏感 | 多活 + 就近接入(GSLB)双重收益 |
| 数据有属地化合规要求 | 按地域部署合规单元 |
| 团队 SRE/分布式经验不足 | 谨慎,先补"主备演练"再考虑多活 |