多活与异地多活架构:同城双活、两地三中心、异地多活、数据同步(DTS)、全局流量管理(GTM)

聊到高可靠性,多活架构是个绕不开的话题。我这些年参与过的系统,但凡对可用性要求高的,最后基本都会走到这条路上来。说白了,单机房再稳,也扛不住一场火灾、一次光纤被挖断。你想想看,用户量上去了,业务不能停,这时候多活架构就成了刚需。

这一章,咱们把同城双活、两地三中心、异地多活这几个概念掰开揉碎。再配合数据同步(DTS)和全局流量管理(GTM),把整个体系串起来。

1. 同城双活:最基础的“多活”形态

同城双活,就是在同一个城市里建两个机房。两个机房都承载业务流量,平时各跑各的,出问题时互相接管。

我最早接触这个模式,是在一个金融项目里。当时客户要求RTO小于30秒,RPO接近零。同城双活是性价比最高的选择。为什么?因为同城光纤延迟低,数据同步能做到毫秒级。

核心要点: 同城双活不是冷备,也不是主备。两个机房都在“活”着,都在处理用户请求。

实现上,有几个关键点:

  • 应用层无状态化:Session信息要外置到Redis或分布式缓存里。我见过一个团队没注意这个,切换时用户全部掉线,被投诉到爆。
  • 数据库层双向同步:常用MySQL的半同步复制,或者用DTS做双向同步。注意冲突处理,比如自增主键要错开。
  • 流量入口做分发:用GTM或者DNS智能解析,把用户流量分到两个机房。
我的经验: 同城双活最怕的是“脑裂”。两个机房之间的光纤断了,两边都以为对方挂了,各自抢着写数据。一定要设计好仲裁机制,比如引入第三方的ZooKeeper集群做决策。

2. 两地三中心:从城市级容灾到区域级容灾

同城双活能扛住机房级别的故障,但扛不住城市级别的灾难。比如地震、洪水、全城停电。这时候就需要两地三中心了。

两地三中心,通常是在同城有两个机房(双活),在异地再建一个机房(冷备或温备)。平时同城两个机房分担流量,异地机房只做数据备份。一旦同城两个机房都挂了,异地机房接管。

我记得有一次做灾备演练,同城两个机房同时“断电”,流量切到异地机房。整个过程花了8分钟,业务恢复。虽然比预期的5分钟长了点,但总算没丢数据。嗯,这里要注意:异地机房的网络延迟高,数据同步不能做到实时,RPO通常在分钟级别。

架构模式 容灾级别 RPO RTO 成本
同城双活 机房级 秒级 秒级
两地三中心 城市级 分钟级 分钟级
异地多活 区域级 秒级 秒级 极高

3. 异地多活:终极形态,但也是最难的

异地多活,说白了就是多个城市都有机房,每个机房都在处理用户请求。用户离哪个机房近,就去哪个机房。这样既降低了延迟,又实现了区域级容灾。

但异地多活的难度,比前两个高了一个数量级。为什么?因为跨城市的网络延迟是几十毫秒,数据同步做不到实时。你想想看,用户在A机房下了单,B机房还不知道,结果用户在B机房又查订单,查不到,这就出问题了。

我参与过一个电商系统的异地多活改造,核心思路是“单元化”。把用户按地域切分成多个单元,每个单元包含完整的业务链路。用户请求只在自己的单元内处理,单元之间通过异步消息同步数据。

关键设计原则:
  • 业务单元化:每个单元是自包含的,能独立完成业务。
  • 数据分片:用户数据按单元归属,不跨单元读写。
  • 最终一致性:单元之间不追求强一致,接受短暂的不一致。

举个例子,用户ID取模,0-4999去北京机房,5000-9999去上海机房。每个机房有自己的数据库,只存自己那部分数据。跨机房的数据查询,通过全局路由表做转发。

4. 数据同步(DTS):多活的“血管”

数据同步是多活架构的命脉。没有它,多活就是一句空话。DTS(Data Transmission Service)是阿里云提供的服务,但原理是通用的。

DTS的核心能力:

  • 实时增量同步:基于binlog或redo log,把源库的变更实时同步到目标库。
  • 双向同步:两个库互相同步,支持冲突检测和自动修复。
  • 结构迁移:表结构、索引、存储过程都能同步。

我曾经踩过一个坑:双向同步时,两边同时修改同一条记录,导致数据冲突。DTS默认的策略是“后写入覆盖”,但业务上可能不是这个逻辑。后来我们改成了“基于时间戳的冲突检测”,谁的时间戳新,谁说了算。

避坑指南: 我曾经在配置DTS时忽略了“DDL同步”选项。结果研发在源库加了个字段,目标库没同步,查询直接报错。记住:DDL变更一定要走审批流程,并且同步到所有节点。

一个典型的数据同步配置示例:

# DTS双向同步配置要点
源库:MySQL 8.0,IP 10.0.1.1
目标库:MySQL 8.0,IP 10.0.2.1
同步模式:双向实时同步
冲突策略:基于时间戳(last_update_time)
过滤规则:排除日志表(log_*)
DDL同步:开启
监控告警:延迟超过5秒触发P0告警

5. 全局流量管理(GTM):多活的“大脑”

GTM负责把用户流量分发到正确的机房。它不像普通的DNS那样只做域名解析,它还能做健康检查、智能路由、故障切换。

GTM的工作原理:

  1. 用户请求域名,GTM返回一个IP地址。
  2. GTM根据用户的地理位置、运营商、机房健康状态,决定返回哪个IP。
  3. 如果某个机房挂了,GTM自动把流量切到其他机房。

我习惯把GTM的配置分成三层:

  • 第一层:全局策略。比如“中国电信用户走电信机房,联通用户走联通机房”。
  • 第二层:地域策略。比如“华东用户走上海机房,华北用户走北京机房”。
  • 第三层:故障策略。比如“如果上海机房健康检查失败,流量切到北京机房”。
我的建议: GTM的健康检查不要只检查端口存活,要检查业务接口。我曾经遇到过机房网络正常,但应用层已经卡死了。GTM还傻乎乎地往那边引流,结果用户全卡住。后来我们改成了检查一个专门的“健康检查接口”,返回200才算正常。

6. 整体架构图

下面这张图,把同城双活、两地三中心、异地多活的关系画清楚了。你可以看到,数据同步(DTS)和全局流量管理(GTM)贯穿其中,是支撑多活架构的两大支柱。

多活与异地多活架构总览 同城双活(城市A) 机房1 应用 + 数据库 承载50%流量 机房2 应用 + 数据库 承载50%流量 DTS双向同步 两地三中心(城市A + 城市B) 同城双活 城市A两个机房 主业务运行 异地灾备 城市B机房 冷备/温备 DTS异步同步 异地多活(单元化架构) 单元1(北京) 用户ID: 0-3999 完整业务链路 独立数据库 单元2(上海) 用户ID: 4000-7999 完整业务链路 独立数据库 单元3(深圳) 用户ID: 8000-11999 完整业务链路 独立数据库 单元4(成都) 用户ID: 12000-15999 完整业务链路 独立数据库 GTM全局流量管理:按地域、运营商、健康状态分发

7. 总结与建议

多活架构没有银弹。同城双活适合对延迟敏感、成本有限的场景。两地三中心适合合规要求高、需要城市级容灾的场景。异地多活适合全球化业务、追求极致可用性的场景。

我个人习惯,在项目初期先做同城双活。等业务规模上来了,再逐步演进到两地三中心。异地多活,说实话,非必要不上。因为复杂度太高,运维成本也大。

最后说一句:无论选哪种架构,数据同步和流量管理都是核心。DTS和GTM这两个工具,一定要吃透。我曾经见过一个团队,架构画得很漂亮,结果DTS延迟没监控,GTM健康检查没配好,一上线就出事故。嗯,细节决定成败。