当前位置: 首页 > 科技观察

如何选择高可用架构?通过这个对比可以了解到常见的多活架构

时间:2023-03-15 14:28:37 科技观察

采用高可用的系统架构来支撑重要系统,为关键业务提供7x24不间断服务,成为很多企业保障业务稳定和持续运行的主要选择。多活服务是高可用架构的重要实现方式。本文介绍了业界常用的同城双活、两地三中心、异地多活架构设计方案等一些业内常用的多活方式,并详述了各种方案的优缺点。1、为什么要多做活动?随着移动互联网的深入发展,用户增长达到一定规模,许多企业将面临业务高并发和海量数据的挑战。传统的单机机房存在机器容量瓶颈。在一些极端场景下,所有服务器都可能出现故障,如机房停电、机房火灾、地震等不可抗力因素会导致系统所有服务器出现故障,导致整体业务瘫痪,以及即使在其他区域有备份,要恢复所有备份的业务系统才能正常提供业务,也需要很长时间。为满足中心业务连续性,增强抗风险能力,多活作为可靠、高可用的部署架构,成为各大互联网公司的首选。1、多活场景多活架构的关键点在于不同地理位置的系统可以提供业务服务。这里的“直播”是指实时提供服务。“活”对应的是“备”字,即备份的意思。一般情况下,不对外提供服务。如果需要服务,需要大量的人工干预和操作,从“准备”变成“直播”需要花费大量时间。单从描述来看,multi-active非常强大,可以保证发生灾难业务不会受到影响,是不是说无论什么业务,我们都要实现多活架构?其实不是,要实现多活架构是要付出一定代价的。具体表现如下:不同的多活方案实现复杂度不同,随着业务规模和容灾级别的提高,多活方案会给业务系统设计带来更多的复杂度;无论采用哪种多活方案,很难完全避免跨机房甚至跨区域服务调用带来的耗时增加;多active会增加成本,毕竟要搭建一个独立的在一个或多个机房系统中结束的一组服务。因此,虽然多活很厉害,但并不是每个业务都需要多活。例如,如果企业内部的IT系统、管理系统、博客网站等无法承受其复杂性和成本,则不必多做异地工作,但有必要多做一些工作核心金融、支付、交易等重要业务。2、多活方案常见的多活方案有同城多活技术方案、两地三中心、三地五中心、异地多活等,不同的多活方案有不同的技术要求、建设成本和运营维护成本。下面我们将逐步介绍这些多活方案,并给出各个方案的优缺点。具体选择何种方案,应根据具体业务规模、现有基础设施建设能力、投入产出比等多方面因素确定。2、同城双活同城双活是在同城或相近区域建立两个机房。同城两个机房距离较近,通讯线路质量好,比较容易实现同步数据复制,保证数据的高度完整性和数据零丢失。同城的两个机房各承担一部分流量。通常,入口流量是完全随机的。内部RPC调用应该通过最近的路由在同一个机房??闭环,相当于在两个机房部署了两个独立的集群,然后实时同步到另一个机房。下图是同城双活的简单部署架构。当然,实际的部署和考虑远比下图复杂:服务调用基本都是在同一个机房??完成的。同步复制到同城备份机房。当A机房出现问题时,运维人员只需通过GSLB或其他方案手动更改路由方式,将流量路由至B机房。同城双活可有效预防火灾、建筑物损坏、电源故障、计算机系统和人为破坏等引起的机房灾害。1、服务路由zk集群:每个机房部署一个zk集群,机房之间zk数据实时双向同步,每个机房都有本机房的所有zk注册数据;路由方案:条件路由>最近路由>跨机房路由,尽量避免跨机房调用;订阅方案:consumer订阅所有机房服务,provider只注册到机房的zk集群。2、数据双活MySQL:采用MHA部署方案,主从半同步方案保证数据一致性。读写分离,读路由到机房就近的数据节点,写路由到主节点所在机房;Redis:Redis集群模式主从同步,就近读写路由到主节点机房。使用原生主从同步跨机房写,性能低。也可以依靠CRDT理论搭建多节点双向同步实现机房附近的读写,但是整体实现起来比较复杂。3、同城双城方案评价1)优势业务同城双活、同城容灾、跨机房级容灾同城不丢包;,通信质量好,MySQL等底层存储可以采用同步复制,有效保证两个机房的数据一致性。2)劣势存在跨机房调用向数据库写入数据,复杂业务和链路下频繁的跨机房调用增加响应时间,影响系统性能和用户体验;保证同城容灾,当服务所在城市或地区整体网络故障,不可抗拒的自然灾害发生时,存在服务故障和数据丢失的风险。对于核心金融业务,至少要有跨区域的容灾能力;服务规模足够大(比如单个应用超过10000台机器),所有机器都链接到一个主数据库实例会导致连接不足。3、两地三中心结构所谓两地三中心,是指同城双中心+异地灾备中心。异地容灾中心是指在异地城市建立备份容灾中心,对双中心进行数据备份。数据和服务通常是冷的。当双中心所在城市或地区出现异常,无法对外提供服务时,异地容灾中心可以利用备份数据恢复业务。两地三中心方案评价1)同城优势服务,同城数据容灾,跨机房级容灾同城不丢数据;架构方案比较简单,核心是解决底层数据双活。通信质量好,MySQL等底层存储可以采用同步复制,有效保证两个机房的数据一致性;容灾中心可以防止同城的两个中心同时出现故障,利用备份数据恢复业务。2)缺点存在跨机房调用向数据库写入数据,复杂业务和链路下频繁的跨机房调用增加响应时间,影响系统性能和用户体验;服务规模足够大(比如单个应用超过10000台机器),所有机器都链接到一个主数据库实例会导致连接不足;如果出现问题,不容易将流量切换到异地数据备份中心。异地备机房冷,一般没有流量进入,如果出现问题异地容灾需要很长时间机房验证。同城双活和两地三中心建设复杂度不高。与同城双活相比,两地三中心有效解决了异地数据容灾问题,但仍然无法解决同城双活的诸多不足。解决这两种架构的缺点需要引入更复杂的方案来解决这些问题。4、异地多活异地多活是指分布在异地的多个站点同时对外提供服务的业务场景。异地多活是一种高可用的架构设计。与传统容灾设计的主要区别在于“多活”,即所有站点同时对外提供服务。1、异地多活的挑战如果应用想要去异地,首先要面对的就是物理距离带来的延迟。如果一个应用请求需要修改异地多个单位的同一行记录,为了满足异地单位之间数据库数据的一致性和完整性,需要付出很高的时间成本;解决异地延迟高,需要单元内读取数据写入关闭,不同单元不能修改同一行数据,所以需要找一个维度来划分单元;访问一个单元内的其他单元数据需要正确路由到对应的单元,比如A用户给B用户转账,A用户和B用户的数据不在同一个单元,用户B的操作可以路由到相应的单元;面临数据同步的挑战,单位关闭的所有数据都必须同步到对应的单位。对于读写分离类型,我们需要将数据从中心同步到单元。2.单元化所谓单元(我们下面将其替换为RZone)是指一个自成一体的集合,可以完成所有的业务操作。该集合包含所有业务所需的所有服务以及分配给该单元的数据。单元化架构是以单元作为系统部署的基本单元,在全站所有机房部署多个单元。每个机房的单元数量是可变的,任何一个单元都部署了系统需要的所有应用。单元化架构下,服务还是分层的。不同之处在于每一层中的任何一个节点都属于并且只属于某个单元。当上层调用下层时,只会选择本单元内的节点。选择哪个维度进行流量细分,需要从业务本身来分析。例如,对于电子商务业务和金融业务,最重要的流程是下单、支付和交易流程。按用户ID拆分数据是最好的选择,买家的相关操作都会在买家的首页。单位内完成。对于商户相关的操作,不能单元化,需要按照下面介绍的非单元化方式进行部署。当然,用户运营业务不能完全避免跨单位甚至跨机房调用。例如,两个买家A和B转让业务。当A和B的数据单元不一致时,需要跨单元完成对B的操作。后面我们会介绍跨单元调用服务路由问题。3.非单元化的应用和数据对于不能单元化的业务和应用,有以下两种可能:对时延不敏感,但对数据一致性非常敏感。此类应用只能部署在同城双活模式。其他应用程序调用此类应用程序时,会存在跨区域调用的可能,必须能够容忍延迟。我们称这种类型的应用程序为MZone应用程序;它们对数据调用延迟很敏感,但可以容忍短期数据不一致。这类应用和数据可以在一个机房保持全量的数据,机房可以增量实时同步。我们暂时称这种应用为QQ空间。除了两个或多个非单元化的应用,我们的机房部署可能是这样的。每个机房有两个RZone,MZone维护着类似两地三中心的部署方式。远程机房调用MZone服务需要跨区域、跨机房调用。但QQ空间每个机房都维护着一套完整的数据,机房之间通过数据链路实时同步。4、请求路由1)API入口网关为了保证用户请求能够正确进入所属单位,每个机房都会部署集群流量入口网关。当用户请求到达机房时,首先进入流量网关。流量网关可以感知全局的流量分片,计算出用户所在的流量单元并将流量转发给对应的单元,从而将用户的请求路由到对应的单元内。使用GateWayr转发方式可以判断用户单位,将用户流量路由到正确的位置,但是HTTP转发也会造成一定的性能损失。为了减少HTTP流量转发量,可以在返回用户请求时,在cookie上携带用户的路由标识信息。用户下次请求时,可以提前获取路由标识,直接向对应单元请求。这种方式可以大大减少HTTP流量转发。2)服务路由虽然应用已经单元化,但跨单元调用仍然不可避免。比如用户A给用户B转账,如果A和B在不同的单位,则需要跨单位调用用户B的操作。这时,就需要将请求路由到B的用户数据所在的单元。RPC、MQ、DB等中间件在远程多活的情况下需要提供路由能力,使请求能够正确路由到相应的单元。下面以RPC路由为例,说明远程多活中间件是如何进行路由的。其他中间件(数据库中间件、缓存中间件、消息中间件等)也采用同样的方法。publicinterfaceManualInterventionFacade{@ZoneRoute(zoneType=ZoneType.RZone,uidClass=UidParseClass.class)ManualRecommendResponsegetManualRecommendCommodity(ManualRecommendRequestrequest);}上面展示了多活下的RPC接口定义方法,需要注明RPC类型,如果是RZone服务必须提供分析液体的方法。下图是RPC注册中心的路由寻址过程,与同城双活有些区别。5、数据同步QZone类数据:这类数据只需要保证最终一致性,对短期不一致没有影响,但是对延迟非常敏感,比如一些算法、风控、配置等数据.这种数据基本上是在每个机房部署一套QZone,然后机房之间相互同步。MZone数据:这类数据对一致性非常敏感,不能有不一致。只能采用同城双活部署,业务需要能够容忍异地通话延迟。RZone数据:此类数据的每个zone都有自己的master节点。如果数据不在单元内,则需要路由到对应的节点写入。该类数据部署如下:六、方案评估1)优势和容灾能力有了很大的提升,服务异地活跃,数据异地活跃;理论上系统服务可以横向扩展,多机房异地突破可以大幅提升整体容量,理论上不会有性能问题;将用户流量切分到多个机房和区域,可以有效降低机房和区域层面故障的影响。2)缺点架构非常复杂,部署和运维成本非常高。需要对公司依赖的中间件和存储进行多方面的改造;路由到对应的单元,业务系统需要设置路由标识(如uid);不可能完全避免跨单位、跨地区调用服务,比如上面的中转业务。我们要做的是尽量避免跨区域服务调用。五、总结本文讨论了多住建设的一些总体思路,一些关键技术点的解决方案,以及各种解决方案的比较。建立完整的远程多活能力远比上述讨论复杂。需要对各种依赖的中间件和存储进行相应的单元改造,提供完整的流量调度和运维管控能力。限于篇幅,本文不详细介绍多活下各种存储(如Redis、MySQL)的数据同步复制和高可用解决方案,有兴趣的同学可以去深入了解这方面的知识。