文章目录
- 异地多活
- 同城单机房多集群
- 同城双机房主备
- 同城双机房多活
- 两地三中心
- 三地五中心
- 异地多活系统设计方法论
- 一个原理:CAP
- 三个原则
- 1、只保证核心业务
- 2、只能做到最终一致性
- 3、只保证绝大部分用户
- 四个步骤
- 1、业务分级
- 2、数据分类
- 3、数据同步
- 4、异常处理
- 五大技巧
- 视频会议-异地多活案例
- 单元化(Set化)
- 异地多活面临的挑战
- 单元化部署
- 分区维度
- 支付宝分区维度
- 饿了么分区维度
- 全局路由网关
- 异地静态主备
- CDN
- CDN与DCDN(全站加速)
异地多活
异地多活:指在不同城市建立独立的数据中心,关键点就是异地、多活,活是指这些数据中心在日常的业务中也需要走流量,多活就是多个数据中心,异地是指在不同的城市建立数据中心。和“活”相对应的是冷,冷备数据中心是指备份全量数据,平时不支撑业务需求。异地多活可以提高机房的容灾能力,一般来讲,机房在高在可用建设的道路上,会有这么几个演进过程:
同城单机房多集群
同城单机房多集群:在同一座城市的单个数据中心里,部署多个互相独立但能进行交互的集群。每个集群都拥有自己的设备和资源,可以独立运行和处理任务。集群间可以互相备份数据和共享资源,提高数据的安全性和系统的可用性,同时也可以根据业务需求进行资源调度和负载均衡,提高系统的运行效率。
城单机房多集群的优点包括:
- 高可用性:在单个机房内部署多个集群,如果一个集群出现问题,其他集群还能正常运行,避免系统宕机,提高了业务的可用性。
- 资源调度:根据业务需求,可以对集群内部的资源进行调度和负载均衡,提高系统的运行效率。
然而,也存在一些缺点:
- 管理复杂:多集群的管理比单一集群复杂,需要更多的时间和精力进行运维。
- 单点故障:虽然多集群架构可以提高系统的可用性,但如果整个机房出现问题,如断电、火灾等,仍可能会导致系统宕机。
同城双机房主备
指在同一个城市设置两个数据中心或机房,其中一个作为主机房,用于运行业务,另一个作为备份机房,用于数据备份和灾难恢复。
在这种架构下,所有的业务运行和数据处理都在主机房进行,同时,主机房的所有数据会实时或定期备份到备份机房。如果主机房出现故障或者不能正常运行时,备份机房可以快速接管业务,保证业务的连续性。
这种架构提高了业务的稳定性和安全性,因为业务运行和数据存储有两套完全独立的物理环境支持,减少了因单一机房故障而导致的业务中断风险。
同城双机房主备的优点包括:
- 高可用性:如果主机房出现故障,备份机房可以迅速接管,确保业务的连续性,从而提高系统的总体可用性。
- 数据安全性:通过双机房实现数据的备份,可提高数据的安全性,减少因单一存储点故障而导致数据丢失的风险。
- 灾难恢复能力强:在遭遇系统故障或灾害等异常情况时,可以快速由备机房接手运行,实现业务的快速恢复。
- 系统维护更加灵活:在需要对主机房进行系统升级、维护或其他改动时,备用机房可以继续提供服务,从而保障业务不受影响。
然而,也存在一些缺点:
- 成本高:与单一机房相比,双机房需要双倍的硬件设备和空间,还需要投入更多的维护费用,成本较高。
- 管理复杂性增加:对于两个机房的管理和维护是一项挑战,需要进行精细化的运维管理和跨机房的资源调度。
- 数据同步延迟:虽然双机房可以进行数据备份,但由于网络等因素,可能存在数据同步的延迟,影响数据的实时性。
- 单点故障仍存在:虽然两个机房可以提高系统的可用性,但如果两个机房都位于同一城市,如遇到地震、洪水等大规模自然灾害,仍可能同时影响两个机房,导致系统宕机。
- 单机房资源瓶颈:单机房资源瓶颈依旧存在,无法得到解决
最重要的一点,备用机房平时是无流量请求,当真正故障发生时,是否敢直接将线上流量全部切入呢?
同城双机房多活
指在同一个城市内设置两个或更多的数据中心,这些数据中心之间数据实时同步,可以同时提供服务,即任何一个数据中心都能接受和处理来自用户的请求。但只有一个机房的数据中心允许写入,其他机房数据中心只能够处理读请求,写请求都代理到主节点,主节点将数据更改行为同步到剩余从数据中心中。
在这种架构下,业务负载会被分配到各个数据中心,每个数据中心都能独立处理请求和进行服务。当某个数据中心发生故障时,其他数据中心仍然可以继续提供服务,数据中心则进行主从切换,避免了单点故障,提高了系统的可用性和健壮性。同时,这种架构也可以根据业务负载进行动态调整,进行负载均衡,提高了系统的处理能力和效率。
同城双机房多活的优点包括:
- 资源利用率高:对于同城双机房主备,有效利用机器资源,不存在资源浪费情况
- 单机房资源瓶颈缓解:由于有多个机房同时提供服务,类似Redis、Mysql 等集群资源得到分担,不会将压力都给到一个机房上
- 可用性高:相对于备份机房只有事故发生时才启用,双机房能够一直提供服务,确保服务一直处于可用状况
然而,也存在一些缺点:
- 单点故障仍存在:虽然两个机房可以提高系统的可用性,但如果两个机房都位于同一城市,如遇到地震、洪水等大规模自然灾害,仍可能同时影响两个机房,导致系统宕机。
两地三中心
为了解决城市级容灾,产生出两地三中心概念。指在两个地理位置(通常是两个城市)部署三个数据中心。这三个数据中心通常配置为:一个主数据中心,一个本地备份中心(位于与主数据中心同一城市,但在不同的地理位置),与一个远程灾备中心(位于另一个城市)。
在这种配置中,主数据中心运行日常业务,同时,本地备份中心对主数据中心的数据进行实时或近实时的备份,用于处理主数据中心的短暂停机或小范围灾害。而远程灾备中心则用于处理主数据中心和本地备份中心同时受到影响的大范围灾害,如地震、洪水等。
在同一城市内的网络传输耗时约为2毫秒左右,而两个城市之间的网络传输耗时则大约为30毫秒(例如北京到上海)。这种较大的延迟会导致灾备中心的数据与主数据库之间存在较大的延时。在灾难发生时,数据可能会丢失,并且服务的可用性也无法得到保证。因此,我们需要将灾备中心转换为一个能够对外提供服务的节点,以分担其他活跃节点的流量。
由于跨城市请求的耗时延迟较大,基础组件需要支持双写或多写功能,不再区分数据中心的主从节点。每个机房都应有自己的数据中心,服务只向自己机房的数据中心进行读写操作,然后再进行数据同步。然而,分布式基础组件都是基于Paxos协议,当有一个机房出现问题时,无法形成多数派,从而导致基础组件无法自动切换。因此,至少需要5个数据中心来确保系统的可靠性和稳定性。
三地五中心
基于两地三中心的缺点,设计出三地五中心方案。
三地五中心的优点包括:
- 城市级容灾:一个城市节点故障时,可以将用户流量切到另一个数据中心上继续处理请求
- 资源利用率高:每个数据中心都可以对外提供服务,没有备份中心,不存在数据浪费
- 用户体验变高:用户可以就近访问数据中心,用户请求耗时更低
然而,也存在一些缺点:
成本高:与上面所有方案相比,需要组件的开发支持,机器与运维的投入,成本较高。
异地多活系统设计方法论
无论什么类型业务,方法论都适应。
- 一个原理:CAP
- 3大原则
- 4个步骤
- 5大技巧
一个原理:CAP
CAP基本原则:
在当前的网络系统中,分区容错性是必要的,因此系统架构一般为CP或者AP架构。
- CP架构保证一致性,在网络故障时拒绝访问。
- AP架构保证服务可用性,在网络故障时,访问其他分区,因此分区之间可能出现数据不一致的情况。
异地多活系统,本质就是一个AP方案,即保证服务的高可用性
CAP细节:
- 粒度:CAP关注的粒度是数据,而非系统,需要根据不同业务数据特点设计异地多活。
- 延迟:CAP是忽略网络延迟的,但工程落地不可能做到0延迟。
- 分区容忍:C和A只能取一个,是指在分区的前提下,正常情况下是可以满足的CA的。
- 补救措施:放弃同时满足C和A,不等于什么都不做。需要为分区恢复做准备,包括人工修复数据。
三个原则
1、只保证核心业务
以一个简单的用户管理系统为例,讨论两个业务场景:
- 注册
- 登录
从业务分析的角度讲,登录是核心业务,而注册不是。
因为一个系统每天登录的业务量远超注册的业务量,而从对价值影响的角度而言,登录业务故障的损失也比注册业务损失要大。(从业务的影响面和影响价值角度分析)
假如用户在A中心,注册后,数据尚未同步到B中心和C中心,A中心宕机了,那么用户此时会转到请求B中心或者C中心,随后发现,用户未注册,那么这时候要给用户注册吗?
从异地多活的角度而言,是应该给用户注册的,但是一旦给用户注册,A中心恢复了,那么就存在注册数据不一致的问题,这时候无论保留哪个中心的数据,都有数据丢失的风险。
登录业务的异地多活会比较好实现,因为登录只需要账号(手机号)和密码,一旦注册后,账号和密码基本上很少变动。
2、只能做到最终一致性
3、只保证绝大部分用户
四个步骤
- 1、业务分级:将业务按照某个维度进行优先级排序,优先保证TOP3业务的异地多活。
- 2、数据分类:分析TOP3中每个业务的关键数据特点,将数据分类。
- 3、数据同步:针对不同的数据分类设计不同的数据同步方式。
- 4、异常处理:针对极端异常的情况,考虑如何处理,可以说技术手段,也可以是非技术手段。
1、业务分级
常用的业务分级维度:
- 访问量
- 核心场景
- 收入来源
2、数据分类
数据分类常见的维度
3、数据同步
常见数据同步方式:
- 二次读取
- 回源读取
- 消息队列
- 数据库同步
4、异常处理
五大技巧
- 1、消息队列同步
- 2、实时改异步
- 3、库存拆分
- 4、适当容忍
- 5、事务合并
视频会议-异地多活案例
单元化(Set化)
异地多活面临的挑战
- 机房之间的延迟:如果只是做同城多活的话,像 2ms的延时不需要考虑,跟同机房相差不大。如果是异地 30 ms的延时就需要重点考虑了,因为如果是反复调用的应用,放大的时间就不只是 30 ms了,可能是 300 ms、500 ms,对很多应用来说是不可接受的。
- 流量路由问题:一个外网的流量进来,该路由到哪个机房处理,是个需要解决的问题。异地机房之间耗时增加就会导致数据同步有延迟,例如用户在A中心注册了,然后访问了B中心,此时B还没有拿到账号数据。
- 数据冲突、同步、一致性问题:用户同时向不同数据中心写入数据,数据中心双向同步数据时,如果出现冲突该如何解决?多活数据可能面临多个写入点,可能会出现错乱、会冲突、循环复制、数据环路等问题。
总结异地多活主要面临传输延迟、流量路由、数据冲突、同步、一致性
五大问题。
单元化部署
单元化是异地多活的解决方案之一,使用单元化可以解决上述异地多活的部分问题。
- 延迟:单元内的业务是自包含的,调用尽量封闭,减少跨机房调用。
- 路由:用户通过路由网关,每次请求到自己所在单元的数据中心,比如用户在A中心,后面用户A的请求会路由到A中心,不会出现访问了B中心,此时B还没有拿到账号数据,但单元化又需要一个新的东西,
全局路由网关
。 - 一致性:将用户按一个规则进行分组,每组用户写入数据时只能写入到指定的数据中心,相当于用户与数据中心绑定在一起,这样就保证数据中心在双向同步之前的数据是不会冲突的,因为按用户分组了,不同用户的数据不会冲突。
异地多活的实现方案有很多种,但不论是纯理论研究,还是一些先行系统的架构实践,都把“单元化部署”推崇为最佳方案,想要基于单元化实现异地多活就必然要解决上面提到的个挑战,异地多活一共有5个挑战:机房之间的延时、流量路由问题、数据冲突问题、数据同步和强一致性,使用单元化后这5个挑战就变成了4个:分区维度、全局路由网关、数据同步和强一致性,因为单元化后,通过请求的分区控制避免了数据传输延迟和数据冲突的问题。
分区维度
不同的业务分区的维度也不同,首先要筛选出可以分区的数据比如订单数据、支付流水数据、账户数据等, 这类数据在系统中的占比越高,整体单元化的程度就越高,如果系统中全部都是这样的数据,那我们就能打造一个完美单元化的架构。
支付宝分区维度
支付宝按用户id维度划分单元,这样的好处是比较简单,且每个单元的数据量相差不大,但转账场景可能会涉及到跨单元,假设一共有10个单元,划分的逻辑是用户id尾号后两位模20,小王的ID是12345666,分片号是66,应该属于Regional Zone 04;而张大妈ID是54321233,分片号33,应该属于Regional Zone 02,下图为支付宝的处理流程
应用层会自动识别业务参数上的分片位,将请求发到正确的单元。业务设计上,我们会保证流水号的分片位跟付款用户的分片位保持一致,所以绝大部分微服务调用都会收敛在Regional Zone 04内部。但支付系统调用账务系统给张大妈的账号加钱的时候,就必须跨单元调用Regional Zone 02的账务服务。图中用红线表示耗时很长(几十毫秒级)的异地访问。现实中并不是所有的数据都可以划片的,支付宝的单元化架构中设计了三种不同类型的 zone:
- RZone(Region Zone):最符合理论上单元定义的 zone,每个 RZone 都是自包含的,拥有自己的数据,能完成所有业务。组内 A/B 集群互为备份,可随时调整 A/B 之间的流量比例。可以把一组 RZone 部署的任意机房中,包括异地机房,数据随着 zone 一起走。
- GZone(Global Zone):部署了不可拆分的数据和服务,这些数据或服务可能会被RZone依赖。GZone 在全局只有一组,数据仅有一份,比如路由规则。也是成组部署的,A/B 互备,同样可以调整流量
- CZone(City Zone):GZone全局只有一份,不同城市的RZone可能依赖GZone服务和数据的时候需要远距离调用,延迟比较大。CZone 解决这个问题的核心思想是:把数据搬到本地,并基于一个假设:大部分数据被创建(写入)和被使用(读取)之间是有时间差的。
时间差假设:举例说明,2 个用户分属两个不同的 RZone,分别部署在两地,用户 A 要给用户 B 做一笔转账,系统处理时必须同时拿到 A 和 B 的会员信息;而 B 是一个刚刚新建的用户,它创建后,其会员信息会进入它所在机房的公共数据库,然后再同步给 A 所在的机房。如果 A 发起转账的时候,B 的信息还没有同步给 A 的机房,这笔业务就会失败。时间差假设就是,对于 80% 以上的公共数据,这种情况不会发生,也就是说 B 的会员信息创建后,过了足够长的时间后,A 才会发起对 B 的转账。
通过对支付宝 RZone 业务的分析发现,时间差假设是成立的,实际上超过 90% 的业务,都对数据被创建和被使用之间的时间间隔要求很低。余下的那些不能忍受时间差的业务(即要求数据被创建后就必须马上可用,要不就干脆不能访问),则必须进行业务改造,忍受异地访问延时。
饿了么分区维度
外卖业务没有按照用户id维度划分单元,原因是外卖的业务场景和上面的支付业务不同,他一共有3个最重要的角色,分别是用户、商家和骑手,如果按照用户id划分单元,那么同一地方的用户、商户、骑手可能被划分到不同 单元,跨机房调用就比较多,所以为了能让外卖订单在一个单元完成内聚,饿了么采用地域划分,选择地理位置作为划分业务的单元,把地理位置上接近的用户,商户,骑手划分到同一个单元。
因为用户是会动的,所以底层数据是要同步的,比如用户从北京到了上海也可以看到自己的订单,但是会有延迟。
全局路由网关
流量管控主要涉及两方面,外部调用的流量和内部调用的流量。
首先,需要有一个全局的流量管控中心,各个应用需要从流量管控中心同步分片规则,流量调整时也需要将规则迅速同步到分布式系统中的各个需要的节点上,在一次请求的整个链路调用过程中,都需要包含分片数据,比如UID,然后计算本次请求需要调用哪个单元的服务。
外部调用的流量指用户发起的流量,一般会先经过DNS解析得到反向代理层ip地址,反向代理层处理请求,然后再请求到网关层,然后到服务层,最后是数据层。总体指导思想是“多层防线,迷途知返”。每层只要能获取到足够的信息,就尽早将请求转到正确的单元去,如果实在拿不到足够的信息,就靠下一层。下图为支付宝的流量管控:
DNS层可以通过多域名来做流量调度,将流量调度规则下发到客户端或者客户端定时从服务端拉取,本地计算好用户单元,直接请求不同的域名。
反向代理层可以根据请求的cookie等标识,将请求转发到对应的网关层。
网关层基本一定可以根据请求信息识别出请求所属的单元,然后调用请求所属单元上的服务。
服务层指RPC调用,在RPC调用的全链路过程中,必须要带上分片数据,然后根据流量管控中心同步过来的分片规则,调用到指定的单元上。需要一个全局服务注册中心,不同单元的注册中心之间互相同步数据,最终所有服务消费者都知道每个单元的服务提供者有哪些,RPC框架就可以根据需要选择调用目标。
最后的数据层,作为请求数据的最后一道防线,保证请求一定写入到正确单元的数据库中。
异地静态主备
CDN
内容分发网络(Content Delivery Network,CDN),其功能是将网络内容发布到最接近用户的边缘节点,使网民可就近取得所需内容,提供网民访问的响应速度和成功率,同时能够保护源站【不暴露真实网站的IP】。解决由于地域、带宽、运营商接入等问题带来的访问延迟高问题,有效帮助站点提升访问速度。
通俗的讲,就是你不用去遥远的服务器去请求数据,而是就近到CDN服务器上去获取你想要的数据,CDN服务器就是把遥远的服务器上的内容缓存到自己身上【同步到自己身上】,让你访问的时候有更低的延迟。
具体来说,CDN就是采用更多的缓存服务器(CDN的边缘节点)分布于用户访问相对集中的地方,当用户访问的时候,利用全局负载技术,将用户的访问重定向到【这里牵扯到CDN专用DNS服务器】距离最近的缓存服务器上,由缓存服务器响应用户的请求,完成访问过程。【概念和边缘计算有异曲同工之妙】
步骤1:用户访问域名url,会首先请求本地DNS解析
步骤2:本地DNS将请求转交给CDN专用DNS解析
步骤3:CDN专用服务器将解析结果IP返回本地DNS服务器
步骤4:本地DNS将解析结果IP返回给用户
步骤5:用户根据解析结果IP访问CDN负载均衡系统【该系统底下有众多的CDN缓存服务节点】
步骤6:CDN负载均衡系统计算出最实惠路径和最近的CDN缓存服务节点
步骤7:CDN负载均衡系统将CDN缓存服务的IP返回给用户
步骤8:用户根据返回的CDN缓存服务器IP访问该服务器
步骤9:CDN缓存服务节点响应用户请求完成整个访问过程。
步骤10:如果CDN缓存服务节点上没有用户请求的资源,就会向源内容服务器同步缓存
步骤11:源内容服务器给CDN缓存服务器同步缓存数据
CDN与DCDN(全站加速)
全速加速(DCDN)是在CDN加速的基础上升级的产品,智能区分访问的是动态还是静态,静态直接调用阿里云CDN加速,动态会通过协议优化等快速回源拉取内容数据。相比于CDN加速只能静态加速资源,DCDN可同时进行静态和动态的加速