单机房的致命风险
你做了负载均衡、做了数据库主从、做了多副本,但所有这些机器都在同一个机房。一旦这个机房断电、断网、或者光纤被挖断——整个系统瞬间全黑,再多副本也救不了。这就是单机房的致命风险:你的高可用只在「单机房不挂」这个前提下成立。
前面讲的备份容灾是出了事用备份恢复,恢复往往要几小时;异地多活追求的是一个机房整个挂掉,另一个机房立刻顶上,业务几乎不停。这是比备份更高级的容灾。
备份是"出事后抢救",异地多活是"出事时无感"。
- 两地三中心两个城市、三个机房,互为备份。
- 单元化把用户按区域分到不同单元,各管各的。
- 跨中心同步数据怎么在两个中心间一致。
- 流量切换一个中心挂了,把流量导到另一个。
两地三中心:是什么
"两地三中心"是个常用说法:两个城市、三个机房。比如同城两个机房(延迟低、互为主备),再加一个异地机房(防城市级灾害)。同城双活负责日常,异地那个负责极端情况兜底。
常见的两地三中心布局:
- 同城 A 机房:主用,日常扛流量
- 同城 B 机房:热备,和 A 实时同步,可随时顶上
- 异地 C 机房:冷备/灾备,防整个城市出事
为什么要"三"?
两个节点之间判断谁活着容易脑裂,
三个节点做多数派投票更稳。
关键是三个节点之间要能做"多数派决策"——断网时靠投票决定谁继续服务,避免两边都以为自己是主。
单元化:把用户切到就近单元
异地多活最理想的形态是单元化:把系统按用户切成多个"单元",每个单元自成一体、自带数据库,用户请求落到哪个城市就由哪个城市的单元服务:
单元化的好处:
- 华南用户 → 广州单元,华南数据在广州
- 华北用户 → 北京单元,华北数据在北京
- 不用跨城读写,延迟低
- 一个城市单元挂了,把那部分用户切到别的城市
这样一来,跨中心的数据同步量大幅减少——每个单元大部分数据是自己管自己的,不用所有操作都跨城同步。这是让异地多活真正跑得动的关键设计。
跨中心数据怎么不冲突
如果同一份数据两个中心都能写,就会打架——A 中心改了用户名字,B 中心也在改,以谁为准?这就是多活最难的地方。常见做法是:关键数据只在一个中心写(归属单元写),其他中心只读;跨中心同步是单向的。
避免数据冲突的原则:
- 一个用户的数据只归一个单元写
- 跨中心只做复制同步,不双向写
- 真要跨单元操作,走异步消息,不实时强写
千万别图省事做"两边都能写",事后数据合不拢比停服还难收拾。
一个中心挂了怎么切流量
广州机房真挂了,怎么把华南用户切走?靠全局流量调度——在最外层(DNS 或全局负载均衡)把原本指向广州的流量,改指到其他城市的备用单元。因为是单元化设计,广州那批用户的数据已经同步到备用单元,切过去就能直接服务。
这里要提前演练:真到出事时才第一次切流量,一定会出岔子。定期做容灾演练,模拟一个中心挂掉,看流量能不能切、数据能不能接上。这和前面讲的故障演练是一套思路。
跨中心延迟的代价
异地多活不是免费的——两个城市之间网络延迟通常十几到几十毫秒。每次跨城访问都带着这个延迟累积起来,用户就觉得慢了。所以单元化才重要:尽量让请求不跨城,跨城只发生在同步数据这种后台场景。
成本也是现实问题:多一个城市的机房,硬件、带宽、运维都翻倍。异地多活是给"不能停"的业务准备的,小站点先把单机房做好备份就够,别一上来就追求三地五中心。
一套最小异地多活方案
如果你现在是单机房,按这个最小路径往多活走:
第一步:先把备份做扎实
- 这是底线,出了事能恢复
第二步:同城加一个热备机房
- 和主机房实时同步数据
- 演练一次主切备,看多久能切过去
第三步:按单元拆业务
- 让用户尽量在就近机房闭环
第四步:加异地灾备机房
- 防城市级灾难,定期演练切换
循序渐进,别一步到位
异地多活是高可用的天花板,也是最贵的。先把单机房的多副本和备份做扎实,再谈同城双活,最后才是异地多活——每一步都有独立价值,不用一步登天。配合前面讲的数据库高可用和故障演练,整套容灾体系就完整了。