共计 5174 个字符,预计需要花费 13 分钟才能阅读完成。
本文首发于 vivo 互联网技术 微信公众号
链接:https://mp.weixin.qq.com/s/OjfFcjnGWV5kutxXndtpMg
作者:vivo 官网商城开发团队
采纳高可用零碎架构反对重要零碎,为要害业务提供 7 ×24 的不间断服务,曾经成为泛滥企业保障业务稳固、继续运行的次要抉择。服务多活是高可用架构重要施行伎俩,本文介绍了一些业界罕用的多活伎俩例如同城双活、两地三核心、异地多活架构设计计划并详述了各种计划的优缺点。
一、为什么要做多活
随着挪动互联网的深刻倒退,用户增长达到肯定规模后,不少企业都会面高并发业务和临海量数据的挑战,传统的单机房在机器容量上存在瓶颈。在一些极其场景下,有可能所有服务器都呈现故障,例如机房断电、机房火灾、地震等这些不卡抗拒因素会导致系统所有服务器都故障从而导致业务整体瘫痪,而且即便有其余地区的备份,把备份业务零碎全副复原到可能失常提供业务,破费的工夫也比拟长。为了满足核心业务连续性,加强抗危险能力,多活作为一种牢靠的高可用部署架构,成为各大互联网公司的首要抉择。
1、多活场景
多活架构的关键点就是指不同地理位置上的零碎都可能提供业务服务,这里的“活”是指实时提供服务的意思。与“活”对应的是字是“备”,备是备份,失常状况下对外是不提供服务的,如果须要提供服务,则须要大量的人工干预和操作,破费大量的工夫能力让“备”变成“活。单纯从形容来看多活很弱小,可能保障在劫难的状况下业务都不受影响,是不是意味着不论什么业务,咱们都要去实现多活架构呢?其实不是,实现多活架构都要付出肯定的代价,具体表现为:
- 不同多活计划实现复杂度不一样,随着业务规模和容灾级别的晋升,多活计划会给业务零碎设计带来更大复杂度。
- 不论采纳哪种多活计划都难以完全避免跨机房甚至是跨地区服务调用带来的耗时减少。
- 多活会带来老本会回升,毕竟要多在一个或者多个机房搭建独立的一套业务零碎。
因而,多活尽管性能很弱小,但也不是每个业务都要上多活。例如,企业外部的 IT 零碎、管理系统、博客站点等,如果无奈接受异地多活带来的复杂度和老本,是能够不做异地多活的,而对于重要的业务例如外围金融、领取、交易等有必要做多活。
2、多活计划
常见的多活计划有同城双活、两地三核心、三地五核心、异地多活等多种技术计划,不同多活计划技术要求、建设老本、运维老本都不一样,上面咱们会逐渐介绍这几种多活计划并给出每种计划的长处和毛病。选用哪种计划要联合具体业务规模、以后根底建设能力、投入产出比等多种因素来决定。
二、同城双活
同城双活是在同城或相近区域内建设两个机房。同城双机房间隔比拟近,通信线路品质较好,比拟容易实现数据的同步复制,保障高度的数据完整性和数据零失落。同城两个机房各承当一部分流量,个别入口流量齐全随机,外部 RPC 调用尽量通过就近路由闭环在同机房,相当于两个机房镜像部署了两个独立集群,数据依然是单点写到主机房数据库,而后实时同步到另外一个机房。下图展现了同城双活简略部署架构,当然个别实在部署和思考问题要远远比下图简单。
服务调用根本在同机房内实现闭环,数据依然是单点写到主机房数据贮存,而后实时同步复制到同城备份机房。当机房 A 呈现问题时候运维人员只须要通过 GSLB 或者其余计划手动更改路由形式将流量路由到 B 机房。同城双活可无效用于防备火灾、建筑物毁坏、供电故障、计算机系统及人为毁坏引起的机房劫难。
1、服务路由
- zk 集群:每个机房都部署一个 zk 集群,机房之间 zk 数据进行实时双向同步,每个机房都领有所有机房 zk 注册数据。
- 路由计划:条件路由 > 就近路由 > 跨机房路由,尽量避免跨机房调用。
- 订阅计划:consumer 订阅所有机房服务,provider 只向该机房 zk 集群进行注册。
2、数据双活
- MySQL:采纳 MHA 部署计划,主从半同步计划保证数据一致性。读写拆散、读就近路由到机房内数据节点、写路由到 master 节点所在机房。
- Redis: Redis cluster 模式主从同步,就近读、写路由主节点机房。采纳原生主从同步跨机房写性能较低,也能够依附 CRDT 实践构建多节点双向同步,实现机房就近读写,然而整体实现较为简单。
3、同城双活计划评估
劣势
- 服务同城双活,数据同城灾备,同城不失落数据状况下跨机房级别容灾。
- 架构计划较为简单,外围是解决底层数据双活,因为双机房间隔近,通信品质好,底层贮存例如 mysql 能够采纳同步复制,无效保障双机房数据一致性。
劣势
- 数据库写数据存在跨机房调用,在简单业务以及链路下频繁跨机房调用减少响应工夫,影响零碎性能和用户体验。
- 保障同城市地区容灾,当服务所在的城市或者地区网络整体故障、产生不可抗拒的自然灾害时候有服务故障以及失落数据危险。对于外围金融业务至多要有跨地区级别的灾备能力。
- 服务规模足够大(例如单体利用超过万台机器),所有机器链接一个主数据库实例会引起连贯有余问题。
三、两地三核心架构
所谓两地三核心是指 同城双核心 + 异地灾备核心。异地灾备核心是指在异地的城市建设一个备份的灾备核心,用于双核心的数据备份,数据和服务平时都是冷的,当双核心所在城市或者地区出现异常而都无奈对外提供服务的时候,异地灾备核心能够用备份数据进行业务的复原。
两地三核心计划评估
劣势
- 服务同城双活,数据同城灾备,同城不失落数据状况下跨机房级别容灾。
- 架构计划较为简单,外围是解决底层数据双活,因为双机房间隔近,通信品质好,底层贮存例如 mysql 能够采纳同步复制,无效保障双机房数据一致性。
- 灾备核心能防备同城双核心同时呈现故障时候利用备份数据进行业务的复原。
劣势
- 数据库写数据存在跨机房调用,在简单业务以及链路下频繁跨机房调用减少响应工夫,影响零碎性能和用户体验。
- 服务规模足够大(例如单体利用超过万台机器),所有机器链接一个主数据库实例会引起连贯有余问题。
- 出问题不敢轻易将流量切往异地数据备份核心,异地的备份数据中心是冷的,平时没有流量进入,因而出问题须要较长时间对异地灾备机房进行验证。
同城双活和两地三核心建设计划建设复杂度都不高,两地三核心相比同城双活无效解决了异地数据灾备问题,然而仍然不能解决同城双活存在的多处毛病,想要解决这两种架构存在的弊病就要引入更简单的解决方案去解决这些问题。
四、异地多活
异地多活指散布在异地的多个站点同时对外提供服务的业务场景。异地多活是高可用架构设计的一种,与传统的灾备设计的最次要区别在于“多活”,即所有站点都是同时在对外提供服务的。
1、异地多活挑战
(1)利用要走向异地,首先要面对的便是物理间隔带来的延时。如果某个利用申请须要在异地多个单元对同一行记录进行批改,为满足异地单元间数据库数据的一致性和完整性,须要付出昂扬的工夫老本。
(2)解决异地高延时即要做到单元内数据读写关闭,不能呈现不同单元对同一行数据进行批改,所以咱们须要找到一个维度去划分单元。
(3)某个单元内拜访其余单元数据须要能正确路由到对应的单元,例如 A 用户给 B 用户转账,A 用户和 B 用户数据不在一个单元内,对 B 用户的操作能路由到相应的单元。
(4)面临的数据同步挑战,对于单元关闭的数据需全副同步到对应单元,对于读写拆散类型的,咱们要把核心的数据同步到单元。
2、单元化
所谓单元(上面咱们用 RZone 代替),是指一个能实现所有业务操作的自蕴含汇合,在这个汇合中蕴含了所有业务所需的所有服务,以及调配给这个单元的数据。
单元化架构就是把单元作为零碎部署的根本单位,在全站所有机房中部署数个单元,每个机房里的单元数目不定,任意一个单元都部署了零碎所需的所有的利用。单元化架构下,服务依然是分层的,不同的是每一层中的任意一个节点都属于且仅属于某一个单元,下层调用上层时,仅会抉择本单元内的节点。
抉择什么维度来进行流量切分,要从业务自身动手去剖析。例如电商业务和金融的业务,最重要的流程即下单、领取、交易流程,通过对用户 id 进行数据切分拆分是最好的抉择,买家的相干操作都会在买家所在的本单元内实现。对于商家相干操作则无奈进行单元化,须要依照上面介绍的非单元化模式去部署。当然用户操作业务并非齐全能防止跨单元甚至是跨机房调用,例如两个买家 A 和 B 转账业务,A 和 B 所属数据单元不统一的时候,对 B 进行操作就须要跨单元去实现,前面咱们会介绍跨单元调用服务路由问题。
3、非单元化利用和数据
对于无奈单元化的业务和利用,会存在上面两种可能性:
(1)延时不铭感然而对数据一致性十分铭感,这类利用只能依照同城双活形式部署。其余利用调用该类利用的时候会存在跨地区调用可能性,要能容忍延时,这类利用咱们称为 MZone 利用。
(2)对数据调用延时铭感然而能够容忍数据短时间不统一,这类利用和数据能够放弃一个机房一份全量数据,机房之间以增量的形式实时同步,这类利用咱们临时称为 QZone。
加上两种以上非单元化利用咱们的机房部署可能是上面这样,每个机房有两个 RZone,MZone 放弃相似两地三核心部署形式,异地机房调用 MZone 服务须要跨地区、跨机房调用。而 QZone 每个机房都放弃一份残缺数据,机房之间通过数据链路实时互相同步。
4、申请路由
(1)Api 入口网关
为了保障用户申请能正确进入本人所属单元,每一个机房都会部署流量入口网关集群。当用户申请达到进入机房内最先进入到流量网关,流量网关能感知全局的流量分片状况,计算用户所处流量单元并将流量转发到对应的单元,这样就能够将用户申请路由到对应的单元内。
采纳 GateWayr 转发形式能够确定用户单元从而将用户流量路由到正确地位,然而 HTTP 转发也会造成肯定性能损耗。为了缩小 HTTP 流量转发量,能够在在用户申请返回的时候在 cookie 上带上该用户的路由标识信息。当用户下次在申请的时候申请的时候能够提前获取到路由标识间接申请到对应的单元,这种形式能够大幅度缩小 HTTP 流量转发。
(2)服务路由
尽管利用曾经进行了单元化,然而仍然无奈防止跨单元调用,例如 A 用户给 B 用户转账,如果 A 和 B 所处单元不同,对 B 用户操作须要跨单元去调用,这个时候须要能将申请路由到 B 用户数据所在的单元。异地多活状况下 RPC、MQ、DB 等等中间件都须要提供路由能力,将申请能正确路由到对应的单元。上面以 RPC 路由为例阐明异地多活下中间件是如何进行路由的,对于其余中间件(数据库中间件、缓存两头、消息中间件等)也是一样办法。
public interface ManualInterventionFacade {@ZoneRoute(zoneType= ZoneType.RZone,uidClass = UidParseClass.class)
ManualRecommendResponse getManualRecommendCommodity(ManualRecommendRequest request);
}
下面展现了多活下的 RPC 接口定义办法,须要注明该 RPC 类型,如果是 RZone 服务必须要提供解析 uid 办法。下图展现了 RPC 注册核心路由寻址过程,和同城双活有肯定的差异性。
5、数据同步
(1)QZone 类型数据:这种数据只须要保障最终一致性,对于短暂不统一无影响,然而对延时十分铭感,例如一些算法、风控、配置等数据。这类数据基本上都是每个机房部署一套 QZone,而后机房之间互相同步。
(2)MZone 数据:这类数据对一致性十分铭感,不能呈现不统一,只能采纳同城双活部署形式,业务须要能容忍异地调用延时。
(3)RZone 数据:这类数据每个 Zone 都有本人的主节点,如果数据不在该单元内须要路由到对应的节点去写。这类数据部署状况像上面这样
6、计划评估
劣势
- 容灾能力大幅度提高,服务异地多活,数据异地多活。
- 实践上零碎服务能够程度扩大,异地多机房冲破大幅度晋升整体容量,实践上不会有性能担心。
- 将用户流量切分到多个机房和地区去,无效能缩小机房和地区级别的故障影响范畴。
劣势
- 架构非常复杂,部署和运维老本很高,须要对公司依赖的中间件、贮存做多方面能力革新。
- 对业务零碎有肯定的侵入性,因为单元化影响服务调用或者写入数据要路由到对应的单元,业务零碎须要设置路由标识(例如 uid)。
- 无奈完全避免跨单元、跨地区调用服务,例如下面的转账业务。咱们要做的是尽力防止跨地区的服务调用。
五、总结
本文探讨了一些多活建设的大体思路以及一些关键技术点的解决方案,各种不同计划比照。要建设起残缺的异地多活能力远远比下面探讨的要简单的多,须要对依赖的各种中间件、贮存等做相应的单元化革新并配套残缺的流量调度和运维管控能力。
因为篇幅限度本文并未具体介绍各种贮存 (例如 Redis、MySQL) 在多活下数据同步复制以及高可用计划,有趣味的同学能够去深刻理解这方面常识。
更多内容敬请关注 vivo 互联网技术 微信公众号
注:转载文章请先与微信号:Labs2020分割