3、同城双活架构:同城双活的定义、同城双活的网络延迟要求、同城双活的存储同步方案、同城双活的典型拓扑

3.1 同城双活到底是个啥?

同城双活,说白了就是在一个城市里,搞两个数据中心。两个中心都跑着业务,都对外提供服务。不像传统的“主备”模式——主库挂了备库才顶上,双活是两边都在干活。

我刚开始接触这个概念时,也觉得挺简单:不就是多部署一套嘛。后来踩了坑才明白,真正的难点不在“部署”,而在“活”字上。怎么让两个中心的数据保持一致?怎么让用户请求能智能分流?流量切过去,用户会话还在不在?这些才是硬骨头。

同城双活的核心目标,是解决单点故障。一个机房挂了,另一个机房能无缝接管。注意,我说的是“无缝”。不是让你半夜爬起来改DNS,也不是让用户重新登录一遍。

同城双活的关键指标:

  • RPO(恢复点目标):接近0,最好就是0。数据不能丢。
  • RTO(恢复时间目标):秒级或分钟级。用户几乎无感知。

3.2 网络延迟要求:别小看那几毫秒

同城双活对网络延迟的要求,其实非常苛刻。两个数据中心之间的距离,通常控制在50公里以内。为什么?因为光速是有限的。

光在光纤里跑,每公里大约需要5微秒。50公里,单程就是250微秒,来回就是500微秒。再加上交换机、防火墙的处理延迟,一个往返轻松超过1毫秒。

你可能会说:“1毫秒而已,能有多大影响?”

嗯,我当年也这么想。直到有一次,我们做存储同步压测,发现数据库写入延迟从0.5毫秒飙到了3毫秒。业务方直接炸了——用户下单页面卡得不行。后来一查,两个机房距离65公里,光纤绕路,实际延迟比理论值高了一倍。

所以,我的建议是:

  • 同城双活,两个机房间的往返延迟(RTT)必须小于2毫秒。这是硬指标。
  • 最好走裸光纤,别经过太多跳转。每多一个设备,就多一份延迟和故障点。
  • 如果条件允许,让运营商做波分复用,直接拉一根物理专线。

避坑指南: 我曾经遇到过,两个机房虽然直线距离只有30公里,但光纤走的是不同运营商的骨干网,绕了一大圈,延迟到了5毫秒。后来我们要求运营商重新拉了一根直连光纤,问题才解决。所以,别只看地图上的直线距离,要实测网络延迟。

3.3 存储同步方案:数据是命根子

同城双活最头疼的,就是存储怎么同步。数据要是对不上,双活就是个笑话。

常见的方案有三种,我一个个说。

3.3.1 基于存储层同步复制

这是最“硬”的方案。存储阵列自己搞定同步,比如华为的HyperMetro、EMC的VPLEX。应用层完全无感知,写一份数据,存储层自动同步到另一个机房。

优点: 对应用透明,改造成本低。

缺点: 贵。非常贵。而且对网络延迟极其敏感,超过2毫秒基本就废了。

3.3.2 基于数据库层同步复制

比如MySQL的半同步复制、Oracle的DataGuard。应用写主库,主库同步到备库,备库确认收到后才返回成功。

优点: 成本可控,灵活性高。

缺点: 对应用有侵入性。读写分离要做好,不然容易读到脏数据。

我个人习惯: 如果业务对一致性要求极高(比如金融交易),我会选存储层同步。如果业务能接受最终一致性(比如内容社区),数据库层同步就够了。

3.3.3 基于应用层双写

应用自己写两份数据,同时写入两个机房的数据库。这方案听起来简单,但坑最多。

我曾经在一个项目中见过这种方案。两个机房同时写,结果因为网络抖动,数据对不上了。最后搞了个对账系统,每天凌晨跑脚本修复数据。嗯,那段时间运维同学天天加班。

我的建议: 除非万不得已,别用应用层双写。一致性太难保证了。

3.4 典型拓扑:一张图说清楚

下面这张图,是我自己总结的同城双活典型拓扑。你一看就明白。

同城双活典型拓扑 用户入口 全局负载均衡(GSLB) 数据中心A 数据中心B 应用服务器 应用服务器 缓存(Redis) 数据库(主) 存储阵列(主) 应用服务器 应用服务器 缓存(Redis) 数据库(备) 存储阵列(备) 数据库同步 存储同步 图例: 数据库同步 存储同步 数据中心边界

这张图里,用户请求先打到全局负载均衡(GSLB)。GSLB根据策略,把流量分到两个数据中心。两个中心的应用层是对等的,都提供服务。

关键在数据层。你看,数据库和存储阵列之间,有两条虚线。一条是数据库同步,一条是存储同步。这两条线,就是双活的核心纽带。

我一般建议,数据库用主备模式。A中心写主库,B中心写备库。备库实时同步主库的数据。如果A中心挂了,GSLB自动把流量切到B中心,B中心的备库升级为主库。整个过程,用户无感知。

注意: 缓存层也要做同步。Redis可以用跨机房部署的Cluster模式,或者用中间件做双写。不然的话,A中心的缓存数据,B中心读不到,用户体验会下降。

3.5 我的一些经验总结

同城双活,说起来简单,做起来全是细节。我最后给你几个实在的建议:

  • 先做压测。 别等上线了才发现网络延迟不达标。提前用工具模拟流量,测出真实延迟。
  • 做好容灾演练。 我见过太多团队,架构画得漂漂亮亮,一演练就露馅。定期断掉一个机房的网络,看看另一个机房能不能扛住。
  • 别追求100%双活。 有些业务场景,比如强一致性的写操作,双活就是很难做。这时候,可以退而求其次,做“主-主”或“主-备”模式。别为了双活而双活。

嗯,同城双活就聊到这儿。记住,架构没有银弹,适合你的才是最好的。


专注资料整理