浅谈业务级灾备的架构模式

1175次阅读  |  发布于2年以前

互联网常见的高可用手段。比如服务冗余部署、异步化设计、负载均衡、服务限流降级熔断、架构拆分、服务治理、分布式存储等等,今天主要是一起聊下,多机房部署的灾备架构模式,来确保服务的高可用。

常见的架构模式

灾备架构比较常见的几种模式,基本分为同城多中心、跨城多中心、跨国多中心。从字面上看,这几个架构模式好像差不多的,只是距离上的差异,其他的感觉都差不多的。但,就是简单的距离上的差异,就会导致在架构上关键的应用场景以及技术本质上有较大的区别。

1. 同城多中心架构

同城多中心最典型的就是双中心跟三中心。

同城双中心

简单来说就是在同一个城市部署两个机房。如下图中,IDC-1和IDC-2。两个机房之间通过高速光纤进行连接。它的一些关键特征是:

(1)相同城市,距离在50km以上。为什么需要在50km以上呢?如果从机房的建设上讲,没有什么不可以,相距5km也可以建设。但我们做双机房,是为了高可用灾备或者备份。一个简单的例子,如果距离过近,很可能是属于一个片区。如果遇到停电,很可能是一个片区的停电。这样两个机房都不可用了。

(2)光纤互联

(3)机房网络延迟<2ms

同城双中心的架构本质是同城双中心可以当做一个逻辑机房。也就是将同一个集群上的节点,部署在两个物理机房。这样可以应对机房级别的灾难。如下图所示

要注意,同一个集群,部署在两个数据中心,一般要用多条光纤线路,不然容易出现脑裂。此外还有些特别情况,如下图,可以发现,如果IDC-2挂了,IDC-1能正常服务。但如果IDC-1整个挂了,DIC-2的Redis集群是不可用的。这是因为sentinel节点不能完成选举,这里要从架构上进行考虑设计。当然也有个办法,就是在idc-3部署一个节点,只部署sentinel集群,来避免这个问题。在IDC-3不需要搭建完整机房,只需要部署部分决策选举相关的服务,有一定成本,但整体成本还是比较低的。

同城三中心

相比同城双中心,三中心就是在同一个城市部署三个机房,相互之间通过高速光纤连接。三中心,每个中心的定位跟职责都是一样的,比如业务要部署的话,三个都会部署。事实上,很少有公司采用这种架构。主要的原因是这种同城三中心的成本是比较高的,但是高可用并没有提高多少,如果发生城市级别的灾难,比如地震、台风等,这三个机房都会受到影响。所以说,想做三机房,一般都是一个同城双中心,然后另外一个机房部署到其他城市。

下图只是示意图,实际的架构要复杂得多。

2. 跨城多中心架构

跨城多中心也分为跨城双中心和跨城三中心或者四中心等。看下图跨城双中心的架构跟同城双中心的架构是类似的,区别就是机房所在城市不一样。跨城双中心的一些关键特征是:不同城市、光纤互联。

跨城双中心主要的应用场景是 :

并不是所有的跨城多中心架构都能满足 这几个应用场景,不同的跨城双中心架构有不同的应用的场景。从城市的距离上,分为近邻城市和远端城市场景。

跨城双中心-近邻城市

这个架构的关键点就是选择两个相近的城市,比如上海杭州、北京天津、广东深圳这种。机房的延时要<10ms,可以当做同一逻辑机房使用。

应用场景:

跨城双中心-远端城市

远端城市架构模式的关键特征是选择两个远距离的城市;机房延时>30ms,不能当作同一逻辑机房;

应用场景

跨城多中心

跨城多中心的一般应用场景,就是用户分区、就近接入、异地多活。

可以结合OceanBase 官方推荐架构来理解。如下图,采用两近(延迟10ms)一远(延迟30~50ms)的部署模式,可以应对城市级别故障,可靠性是最高的;不过成本也是最高的。为什么要2近1远?其实这跟oceanBase本身的技术实现有关系,底层为了保证一致性,是通过proxy协议不断的进行通信、投票来保障的,必须要保证服务之间通信的性能。一远是为了保证应对城市级别的故障。

3. 跨国数据中心架构

跨国数据中心

跨国数据中心的基本特点:

(1)全球部署

(2)合规和监管,不同的地区的数据法规不一样,比如用户的隐私信息之类的

(3)区域用户分区

(4)不能做异地多活。一个原因是时间延迟问题,另外还是在于合规跟监管,不同地区的合规跟监管数据隐私保护的不一样,没办法做异地多活。

可以看下Google和Facebook的跨国数据中心,上面的图是Google的下图是Facebook的

跨国数据中心。主要部署在北美、欧洲、亚洲区。

4. 五种架构对比

主要从应用场景维度看下几种架构的区别

像常见的冷备、双机热备、同城双活、异地双活、异地多活基本都是集合自己的业务场景及发展阶段对以上几种架构模式的应用。我们下面主要说下异地多活的集中模式。

异地多活的三种模式

异地多活的落地可以概括为有三种大的模式,业务定制型异地多活、业务通用型异地多活、业务存储型异地多活。

1. 业务定制型异地多活

简单来说,业务定制型异地多活,就是按照业务的优先级进行排序,优先保证核心业务异地多活。然后基于核心业务的流程和数据,设计定制化的异地多活架构。但是A业务做的方案,并不能直接用到B业务上。比如说电商业务做的双活,不能用到社交的业务上,架构的方案并不通用。

如下图中的示意图:

这种模式的优点就是:对基础设施没有强要求,例如机房部署、存储系统、时延等,一般是部署在远距离的两个城市,可以支持区域级别故障处理。 缺点也比较明显,不通用,每个业务都需要单独来做异地多活,业务需要改造。难扩展,核心业务如果有重大变化,异地多活方案需要重新设计。

2. 业务通用型异地多活

这种方式一般是通过配套服务来支持异地多活。相对于业务定制型架构,一般无需按照优先级排序来挑选某些业务实现异地多活,只需要判断业务是否能异地多活,当然,业务实际落地的时候可能会有阶段或者灰度过程,并不是一步到位。这种架构的优缺点:

a. 对硬件基础设施没有强要求,例如机房部署、存储系统、时延等,一般部署在远距离的两个城市,可以支持区域级别的故障处理。

b. 业务基本不做改造或做较小的改造,只需要判断业务是否支持BASE,支持就可以做异地多活,不支持就单点部署。这个也是要依赖业务系统前期的设计。

a. 配套服务复杂,包括流量调度、容灾切换、建站平台、配置管理等

b. 存在全局单点业务。例如库存、卖家等相关业务

机房距离较远的时候,RTO比较大,可能达到分钟级。异地多活基础理论是Base,一定时间内达到最终一致,这个时间范围可能会较长,有可能会达到分钟级。

示意图

「案例 」淘宝的单元化架构

把业务分成很多个单元,每个业务绝大部分请求都可以在本单元内完成。不同的用户划分到不同的单元。除了单元还有个中心点。比如库存信息,全量的商品及卖家数据。再把数据复制到各个单元去。

示意图

【单元】单元(即单元化应用服务产品层的部署单元),是指一个能完成所有业务操作的自包含集合,在这个集合中包含了所有业务所需的所有服务,以及分配给这个单元的数据。单元化架构就是将单元作为部署的基本单位,在全站所有机房中部署多个单元,每个机房内单元数目不固定,任一单元均部署系统所需的全部应用,数据则是全量数据按照某种维度划分后的一部分。

3. 存储通用型异地多活

基于业务通用性架构去做,有的业务不能满足base理论,就不能实现异地多活。那有没有一种方法,与业务不强相关,实现多活的架构设计呢?答案肯定是有的,从存储系统来实现,采用本身已经支持一致性的存储系统,实现存储通用型异地多活。

存储通用型异地多活架构方案的优点就是天然支持异地多活,业务除了切换存储系统外,其他基本不做改造。也不需要分析自己的业务场景、优先级。

缺点就是

(1)需要分布式一致性的存储系统支持。目前这样的存储系统可选不多,例如zookeeper、etcd、OceanBase。实际上zookeeper、etcd不适合存储大量数据的。

(2)对机房部署有强要求,如果实现异地多活,只能采用近邻部署。分布式一致性框架,是需要通过协议通信的,这个对性能跟速度要求是有要求的,如果是分布式存储系统之间的节点,通信性能很差的话,那么会导致这个系统的读写性能会很差,就满足不了业务需求了。

「案例」 蚂蚁的OceanBase

目前为止,OceanBase是比较典型的一个分布式存储,而且是真正落地的一个分布式一致性存储系统。简单理解OceanBase就是一个基于Paxos算法来实现的分布式一致性存储系统。【参考官方介绍】

如上图,简单理解:

(1) Zone 是一个机房内的一组服务器,包含多台 OceanBase 数据库服务器(OBServer), 一般会把数据的多个副本分布在不同的 Zone 上,可以实现单个 Zone 故障不影响数据库 服务。

(2)每台 OBServer 包含 SQL 引擎、事务引擎和存储引擎,并服务多个数据分区,其中,每 个 Zone 有一台 OBServer 会同时使能总控服务(RootService),用于执行集群管理、服 务器管理、自动负载均衡等操作。

(3)OBServer 上会运行 SQL 引擎、事务引擎和存储引擎,用户的 SQL 查询经过 SQL 引擎 解析优化后转化为事务引擎和存储引擎的内部调用。

(4)OceanBase 数据库还会执行强一致的分布式事务,从而在分布式集群上实现数据库事务 ACID。(参考链接 :https://zhuanlan.zhihu.com/p/41139701)

参考下图理解,部署上一般要求2近1远,距离相近的两个城市,每个城市的机房都要部署2个Zone,较远的城市部署一个Zone.

「案例」蚂蚁的LDC架构

结合淘宝单元化的架构+OceanBase

示意图

如上图,简单理解:

RZone(Region Zone):部署按用户维度拆分 的关键业务系统。核心业务和数据单元化拆分,每个单元内尽量调用闭环, 拥有自己的数据,能完成所有业务。一个可用区可以有多个RZone。

GZone(Global Zone):部署未按用户维度拆分的系统,全局只有一份,被 RZone 依赖,提供不可拆分的数据和 服务,如配置型的业务。数据库可以和 RZone 共享,多租户隔离,全局只有一组,可以配置流量权重。

CZone(City Zone):部署未按用户维度拆分的系统,被 RZone 高频访问 ,解决跨域通信延时问 题。为了解决异地延迟问题而特别设计,适合读多写少且不可拆分的业务。以城市为单位部署的单元,一般每个城市一套应用和数据,是 GZone 的只读副本。

可以自行看下支付宝的案例介绍。(支付宝案例链接:https://www.sohu.com/a/406634738_99940985)

4. 三种模式对比

从应用场景和实现成本上看下三种模式各有优缺点

异地多活架构关键技术(通用型)

大厂一般常用的方案是通用型的技术方案。我们重点说下业务通用性的架构上的一些关键实现。

1. 流量调度

主要是负责将用户的请求流量分配到对应的单元,例如蚂蚁的Spanner。Spanner 是蚂蚁金服的七层网络代理 ,承载了蚂蚁金服所有的业务流量,包括支付宝 App、Web、商户等的终端访问。

如下图,用户通过蚂蚁金服的网络入口进来,通过多协议接入,到 LVS 和 Spanner,Spanner 作为统一七层网关把请求分发给后面的应用。在 Spanner 上有很多业务逻辑、协议支持,比如 TLS 1.3、QUIC、HTTP 以及蚂蚁自研的协议等。蚂蚁的所有业务,包括支付宝钱包、其他页面都是通过这个入口进来。

下图是spanner在三地五中心架构中的流量调度的场景,也可以发现,通过流量调度可实现:

2. LDC路由

异地多活架构下的路由中心,一般分三层。第一层是判断决定访问哪个机房或单元。第二层是在服务间调用的时候,来判断请求应该到哪个单元。第三层是到访问数据层,最后一层的兜底,决定访问到哪个DB.

结合蚂蚁的架构,看下路由情况

【入口流量路由】

箭头1:对于应该在本 IDC 处理的请求,就直接映射到对应的 RZ 即可;

箭头2:不在本 IDC 处理的请求,Spanner 可以转发至其他 IDC 的 Spanner。

【服务路由】

RPC调用、MQ的一些场景,有些场景来说,A 用户的一个请求可能关联了对 B 用户数据的访问,比如 A 转账给 B,A 扣 完钱后要调用账务系统去增加 B 的余额。这时候就涉及到:

箭头3:跳转到其他 IDC 的 RZone;

箭头4:跳转到本 IDC 的其他 RZone。

【数据路由】

RZ 访问哪个数据库,是可以配置的,对应图中箭头5。

3. DRC

(Data Replication Center):数据复制中心,主要是支持异构数据库实时同步,数据记录变更订阅服务。为业务跨域实时同步、实时增量分发、异地双活、数据双向同步、数据巡检、redis invaild等场景提供支持。可以参考otter的架构设计。

单机房同步

如上图所示:

数据on-Fly,尽可能不落地,更快地进行数据同步。(开启node loadBalancer算法,如果Node节点S+ETL落在不同的Node上,数据会有个网络传输过程)。Node节点可以有failover / loadBalancer。

异地多活同步

如上图所示:

数据涉及网络传输,S/E/T/L几个阶段会分散在2个或者更多Node节点上,多个Node之间通过zookeeper进行协同工作 (一般是Select和Extract在一个机房的Node,Transform/Load落在另一个机房的Node)。

Node节点可以有failover / loadBalancer. (每个机房的Node节点,都可以是集群,一台或者多台机器)。

4. DAL

DAL是proxy型的数据库中间件,支持mysql协议。在多活项目中,DAL责无旁贷扮演起保护数据正确性最后一道防线的角色。

对于个别一致性要求很高的应用,一般提供了一种强一致的方案,比如饿了么的架构中的Global Zone,Globa Zone 是一种跨机房的读写分离机制,所有的写操作被定向到一个 Master 机房进行,以保证一致性,读操作可以在每个机房的 Slave 库执行,也可以 bind 到 Master 机房进行,这一切都基于数据库访问层(DAL)完成,业务基本无感知。

5. 配置中心

负责Zone的配置和容灾切换,例如RZone的业务范围,Zone访问哪些数据库等。

6. 发布平台

服务多机房的发布。基于流量调度,完成Zone的蓝绿发布、灰度发布等。

7. 建站平台

快速新建一个完整的单元,包含机器搭建、基础设施搭建,服务部署等,目前基本都是基于容器技术实现的。

异地多活架构设计的方法

在实际的落地过程中,还是有一些通用的架构设计方法来做参考。

1. 异地多活 - 3大原则

完美是优秀的敌人,不能过于追求完美。在落地异地多活的时候,一般要遵守3个原则

(1)只保证核心业务。不同业务的数据特性不同,无法全部做到异地多活

(2)原则上只能做到最终一致性。复制肯定有时间窗口,抛弃实时一致性的想法。可以了解下【PACELC理论】

(3)只能保证绝大部分用户。不能为了0.01%的用户,影响到99.99%的用户。

2. 异地多活 - 4个步骤

(1)业务定级

将业务按照某个维度进行优先级排序,有限保证Top3业务异地多活。一般定级的方向,可以从访问量、核心场景、收入来源看。

访问量:登录>注册>修改密码核心场景:交易>社区收入来源:订单>搜索>编辑 (2)数据分类

分析TOP3中的每个业务的关键数据特点,将数据分类。

(3)数据同步

针对不同的数据分类设计不同的数据同步方式。

(4)异常处理

针对极端异常的情况,考虑如何处理,可以是技术手段,也可以是非技术手段。

异地双活实践

1. 概述

下图是当前得物双活架构的业务示意图,包含了路由中心、DRC、DAL、配置中心等基础设施。

如图所示,用户在app发起请求后,客户端会先根据缓存的信息,判断该用户应该访问到哪台SLB,然后SLB将请求转发到DLB,DLB会根据最新的路由规则,判断该用户是否属于本单元,如果是继续在本单元流转,如果不是,将请求转发到相应单元。如图中绿色请求所示,该用户实际规则应该路由到B机房,实际请求到A机房后,在DLB层也会将请求转发到B机房。应用服务注册的时候会标记自己的地址、服务类型。以便通过RPC服务间调用的时候进行路由。

在异地双活落地的过程中,重点说下需关注的几个点。

2. 重点模块

数据拆分

从业务角度分析,最主要的是数据拆分。每个单元有部分用户的数据,用户尽可能地在本单元完成所有的行为操作。对于非用户维度的数据,部署在中心单元(机房),向单元机房做单向同步。为了灾备,用户维度的数据,单元机房和中心机房之间会双向同步。

数据架构示意图

数据同步

按照业务的拆分规则,单元模式的数据,不同的用户会在不同的单元进行写入。单元和中心之间会双向同步。另外一种是中心模式的数据,这部分数据在中心写,全量同步到单元。可在单元进行访问。如果当前库既有单元模式的物理表又有中心模式的物理表,不建议混合在一起,最好进行拆分。

单元化模式:两边都会写入,双向进行同步,保证两边都有全量数据。保证在流量切流后,用户访问数据不受影响。

单向复制模式:只在中心写入,向单元全量同步,属于单元只读。

还有一种是仅在中心部署的,比如库存数据,有强一致性要求,只在中心部署。数据的同步是通过DRC来完成的。

RPC服务框架

主要是通过rpc框架,让开发者不需要关心调用服务的细节。provider 将自己的服务,注册到注册中心,consumer从注册中心拉取服务,并进行消费调用。在rpc框架内部,缓存了路由策略。可以直接在consumer获取服务时,根据规则进行筛选。让服务间的调用较简单。而且也提高了路由调度的灵活性。比如机房就近调用,单元化路由调用等。这也是上述LDC路由中的第二层路由。

一般的单元化规则:

(1)哪些用户属于哪个单元

(2)哪些应用属于单元

但实际应用中,还有比较复杂的场景,从应用场景上,目前主要是分为三种:普通服务,单元服务,中心服务。

【普通模式】的服务就是没有做单元化改造的服务,没有单元的概念。服务间调用是就近调用,也就是本单元优先调用,如果本单元没有,会去中心调用。中心对普通服务的调用,也是直接调用中心的普通服务。

【单元模式】的服务是单元化路由服务,会根据路由key(用户ID),将请求进行路由到正确的单元。

【中心模式】的服务,尽管在中心和单元的注册中心都会注册,但请求最终只会路由到中心去。

缓存失败

做了双活之后,缓存失效的逻辑也会有一定变化。大部分应用,原缓存失效逻辑是:应用发起数据更新操作,先更新DB的数据,再进行缓存失效的处理,下次有请求的时候,数据从DB加载到缓存。

但做了双活之后,中心的数据发生变更,单元的缓存也要做失效处理。但单元的缓存失效不能直接依赖中心DB的变更消息。如果直接依赖中心DB的变更消息,单元的缓存失效有可能在单元DB 变更之前失效,此时用户来访问,可能把旧数据写入缓存,导致数据不一致。

所以目前的解决方案是,通过DRC,将中心的DB数据同步到单元,单元DB变更后,会通过DRC把binlog发送到MQ,应用再去操作缓存失效或更新。

MQ消息

MQ中间件也是需要做改造的,要保证消息能够落到正确的单元,并在正确的单元消费。

做双活前原有的的逻辑,大部分是接受消息后,对数据进行插入或更新操作。如果做了单元改造的库,部分数据已经根据相应策略划到对应单元写入,这时消息却在中心进行消费,这会导致两边双写,出现脏数据。这就需要MQ也有有路由的能力,让消息路由到正确的单元,不仅仅是依赖RPC框架或DAL 层的路由限制。

目前的方案,消息会双向复制。根据消费方配置的订阅方式,进行订阅消费。

3. 容灾能力&策略

(1)切流步骤

(2)容灾场景

单元机房出现故障,可以将流量切到中心新房

中心机房故障,当前的方案不能解决。可以在后续做到中心故障切换到中心备份环境,或者说,中心机房做逻辑机房,增强中心机房的抗灾能力。如下示意图

【附录】

常见的几个核心指标含义

【RTO】(Recovery Time Objective),即恢复时间目标。主要指的是所能容忍的业务停止服务的最长时间,也就是从灾难发生到业务系统恢复服务功能所需要的最短时间周期。RTO描述了恢复过程需要花费的时间。例如:假设在时间点t1启动恢复过程并且在时间点t2完成恢复,那么RTO就等于t2-t1。RTO值越小,代表容灾系统的数据恢复能力越强。RTO=0就意味着在任何情况下都不允许目标业务有任何运营停顿。

【RPO】(Recovery Point Object)恢复点目标,指一个过去的时间点,当灾难或紧急事件发生时,数据可以恢复到的时间点,是业务系统所能容忍的数据丢失量。例如每天00:00进行数据备份,那么如果今天发生了宕机事件,数据可以恢复到的时间点(RPO)就是今天的00:00,如果凌晨3点发生灾难或宕机事件,损失的数据就是三个小时,如果23:59发生灾难,那么损失的数据就是约24小时,所以该用户的RPO就是24小时,即用户最大的数据损失量是24小时。所以RPO指的是用户允许损失的最大数据量。这和数据备份的频率有关,为了改进RPO,必然要增加数据备份的频率才行。RPO指标主要反映了业务连续性管理体系下备用数据的有效性,即RPO取值越小,表示系统对数据完整性的保证能力越强。

可以通过下图来对比RTO和RPO。

从图中不难看出,RPO指标来自于故障发生前,而RTO指标来自故障发生后,两者的数值越小,就能有效缩短业务正常到业务过渡期的时间间隔,单一地提升RTO或RPO指标也可以缩减业务故障到过渡期的时间,具体从哪个指标上来改善,就要结合的实际情况分析,提升那个指标代价最小,效果更明显。

【WRT】(Work Recovery Time),工作恢复时间,指“系统恢复正常后,恢复业务所需的时间”,因为要进行各种业务检查、校验、修复。

【MTD】(Maximum Tolerable Downtime),最大可容忍宕机时间,等于 RTO + WRT。

参考资料:

李运华《从0开始学架构》《架构实战专栏》

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8