三地五中心部署架构演化进程

“三地五中心”,这是一种机房架构,即在三座城市部署五个机房,一旦其中一个或两个机房发生故障,依靠技术可以将故障城市的流量全部切换到运行正常的机房。

1)集群部署

假设我们开发的应用都部署在一台服务器上,当这个服务器挂了的时候,我们的应用就不可用了,所以我们应用一般都是集群化部署在多台机器上的,这样一台机器出问题了并不会影响我们的应用。

oceanbase三地五中心容灾架构 三地五中心多活架构_微服务架构

2)同城双活

集群化部署以后,假设某一天公司机房所在地区发生了不可抗拒的因素导致停电断网(比如电缆/光纤被蓝翔给挖了)等,这个时候我们可以考虑在同城的另一个地区再搭建一个机房【这就是同城双活】,来应对这种突发情况。

oceanbase三地五中心容灾架构 三地五中心多活架构_数据中心_02

3)异地多活

同城双活部署以后,假设有一天整个城市都遭遇了不可抗拒的打击(自然灾害或人为因素)导致两个机房都不可用了,这个时候我们就应该考虑在另外一个城市再搭建一个机房【这就是异地多活】。这样的话,我们的应用基本99.99%可用,除非遇到世界末日或者竞争对手人为同时多地搞破坏…

oceanbase三地五中心容灾架构 三地五中心多活架构_微服务架构_03

同城灾备,异地容灾

如果只考虑简单的读应用,不考虑写前三种就可以应对了,但实际上应用的写需求是少不了的。所以不同机房的应用不能同时对外提供写需求,因为这样会导致数据冲突。因此如果只保证一个机房(主机房)的写需求,其他机房(容灾机房)从主机房同步备份数据即可。

4)两地三中心

当主机房挂了,启用同城备机房,同城备机房也挂了,就启用异地备机房。仔细品,其实每次都只有一个机房对外提供服务,两外两个机房都被用来容灾,也就是说备用机房利用率不高,因为主机房不可能老出问题,这样就导致主机房“累死”,备机房“闲死”。所以,我们可以尝试把一些对数据实时性要求不高的请求或不太重要的业务请求交给同城备用机房去做,而异地备机房还是只做容灾,因为异地数据同步延迟高,不能保证异地备机房处理业务时,数据是一致的【这时架构就变成了两地三中心】。 如下:

oceanbase三地五中心容灾架构 三地五中心多活架构_微服务架构_04

两地三中心这种架构是目前很多银行或大型企业正在使用的一种架构,因为国家针对银行的灾备能力做过要求,资产超过多少多少的一定要做两地三中心架构,以保证银行系统的稳定。

那么这种架构有没有它的缺点呢? 这种设计架构,各个数据中心之间是需要相互备份数据的,而数据备份只有两种方式,要么异步,要么同步。

最大性能模式:
	如果是异步,表示用户一个写数据请求,只要在生产数据中心存储完数据后就会直接返回结果给用户,同时异步去备份数据,但是,如果正准备去异步备份数据的时候生产数据中心停电了~,那么这个时候还能将灾备服务器暴露出去给用户提供服务吗?不能了,因为很有可能灾备中心的数据是过时的数据。
	
最大保护模式:
	如果是同步,表示用户一个写数据请求,不仅要等待生产数据中心存储完数据,还需要等其他灾备中心备份完数据后才能返回,而且仅仅当灾备中心出现问题时,因为不能完成数据的备份,所以整个架构也不能对外提供服务,这种可用性是很低的。
最大可用模式:
	这是普遍采用的方案,正常情况下使用最大保护模式,同时生产数据中心监控灾备数据中心,一旦发现某一灾备中心出现了问题,那么则会改为最大性能模式,这样就保证了生产数据中心不受其他灾备中心影响。

三写两同步:
	这是阿里之前的架构模式,意思是同城三个中心,数据备份不是发生在数据库层面,而是应用层,当应用向数据库去写数据时,会同时向三个中心去写数据,只要有两个中心返回成功即可,这样就算三个中心有一个中心停电了,那么并不影响整个架构的高可用,这个思路和我们前面三种是不一样的,性能肯定会高很多。

总结一下两地三中心的缺点:

  1. 灾备中心利用率不高
  2. 生产数据中心停止运行后,灾备中心中不一定有100%一模一样的数据
  3. 成本高,但又无法真正实现期望的高可用能力

那么为了解决这个问题,就出现了**三地五中心,**虽然名字和两地三中心类似,但提供的功能完全不同。 三地五中心是指三个城市,5个中心, 三地五中心基于的概念是单元化架构。

5)三地五中心

两地三中心这种架构已具备了容灾能力,但是当主机房真出现问题了,备机房并不能马上投入使用,因为再启用备机房之前还要做很多的检查和准备工作,这个时间是不确定的,但可以肯定不会很快…

灾备中心它主要的功能是作为生产数据中心的一个备份,所以它并没有如同生产数据中心一样不停的在对外提供服务
第一,不能保证灾备中心有能力接管线上所有的用户流量,可能刚已接收灾备中心被压垮,或者出现其他各种各样预估不到的错误;
第二,如果生产数据中心接收了用户的写请求,还没来得及同步到灾备中心,这个时候停电了,这种情况下,也不能直接把用户流量切到灾备中心。

那么问题来了,该怎么办?

首先对于上面列出来的两点中的第一点,如果我们能够让灾备中心不再仅仅只能用来做灾备,还能和生产数据中心一样正常的对外提供服务呢?如下图:

oceanbase三地五中心容灾架构 三地五中心多活架构_微服务架构_05

可以看到上面的架构图:

  • 不再区分生产数据中心和灾备数据中心,只有数据中心,而且数据中心之间相互备份数据,保证每个数据中心都是全量数据。
  • 用户可以在任意一个数据中心上进行读写操作。

好,首先我们不管这种架构能不能实现,至少它的好处是非常明显的:

  1. 每个数据中心一直在对外提供服务(不是一个新手),所以当一个数据中心停电后,直接把用户流量切到另外一个数据中心也是问题不大的。
  2. 用户可以就近访问数据中心,这样用户的体验更好,并且整个架构的流量也比较平均。

优点很明显,如果能实现就再好不过了,那么这种架构实现起来最重要的一点就是:用户同时向不同数据中心写入数据,数据中心双向同步数据时,如果出现冲突该如何解决? 对于这个问题,目前阿里和蚂蚁金服的解决办法是:将用户按某一个规则进行分组,每组用户写入数据时只能写入到指定的数据中心,相当于用户与数据中心绑定在一起了,这样保证了数据中心在双向同步之前数据是不会冲突的,因为按用户分组了,不同用户的数据不会冲突。 当然思路非常简单,但是实现起来肯定是非常麻烦的,但是思路肯定是可以的,阿里也用实践证明了,我们先把上面的架构稍微完善一下:

oceanbase三地五中心容灾架构 三地五中心多活架构_数据架构_06

比如:按登录地区【也可以按注册地,常用登录地,户籍所在地等分组】给用户分组:用户请求来时,通过流量入口判断用户所在城市路由到最近的城市所在机房,之后用户的所有读写请求都在此机房完成,然后同步至其他机房…所以,现在系统会变得更加健壮了。

  • 现在如果city1机房1不可用了,我们可以通过调整负载均衡把city1机房1的用户流量切到city1的机房2去
  • 如果只是city1机房1部分数据库分片不可用了,我们也可以通过一定规则把这部分用户流量平滑的切到city1的机房2上
  • 如果整个city1的机房都不可用了,那么可以通过负载将流量整体迁移到city2去。

这个架构中最重要的其实就是用户分组,所以包括我们的应用程序、数据库负载均衡、数据库分表等等都需要按用户进行分组,我们要保证针对同一个用户的请求与操作都在同一个机房内,不去跨机房,这样才是最快的,这就是单元化

那么上面这个架构实际上就是一个高级版的“两地三中心”,只是这种单元化架构我们可以随意去扩展(只要足够有钱),比如扩充成五个数据中心,那么就如下图所示:

oceanbase三地五中心容灾架构 三地五中心多活架构_数据中心_07