基本概念

机房

核心机房:以后单机房状况下的机房,除了双活的业务外,长尾业务以及没做多活的业务都在该机房。

单元机房:新机房,即双活新增的机房,用以承接主链路双活能力流量的机房。

路由

sharding_id即route_code,双活依据路由规定会转换为route_code(四轮出行为地区)。每个route_code会对应核心机房或者单元机房。网关、soa、redis、db等都会依据route_code路由到正确的机房。

多活的几种模式

同城双活

在同个城市进行双活部署(两个IDC)。

异地双活

在两个城市进行双活部署(每个城市一个IDC)。

异地多活

在多个城市进行多IDC部署。

优劣势

模式劣势劣势
同城双活物理间隔短,底层数据同步提早较低,rpc接口跨机房调用提早也较低。双活灾备能力不够(同城断电状况就无奈做到双活)。
异地双活灾备绝对同城多活状况较好,能够应答城市级别劫难。绝对同城间隔长,底层数据同步提早绝对较高,rpc接口跨机房调用提早也绝对较高。
异地多活灾备绝对双活有肯定晋升。多活之间因为波及多IDC的数据同步,数据同步提早、数据一致性对账计划也会较为简单,且链路提早也会存在肯定的增长。

单元化

大家能够思考一个问题,一个公司,或者某个业务在tps达到几十万或者几百万在整个零碎设计、架构乃至机房瓶颈就会显得极为突出。然而放眼整个国家或者寰球来看,全副的tps何止百万、千万,归根结底还是因为不同的流量,在最开始就依据公司、业务、机房、地区路由到了不同的机房,而因为公司、业务之间人造是隔离的,因而每个公司的每个业务只须要解决本人的这部分tps就行。如:淘宝流量只会在阿里的利用、机房,滴滴的流量只会在滴滴的利用、机房。然而如果某个公司的某个业务的tps有一亿,如果无奈做到程度有限扩容,必然是没有公司可能抗住这么大的并发的,不光是架构,即便物理机房也不容许这么大的集群(电力、场地都会有限度)。而单元化提供了实践上有限程度扩容的架构能力。

单元化能够了解为异地多活的最终状态。单元化在流量入口将流量拆分到不同的IDC,每个IDC别离承接本人的流量,且IDC之前的流量不会相互调用。单元化和区域无关,实践上做到单元化后,新增的流量齐全能够新增IDC解决,而新增的IDC不会受到区域的限度,因为IDC之前不会有流量相互调用。

判断是否做到单元化,我了解只有一个规范,即是否流量可能自闭环。举个例子,如果你的A机房在上海部署,B机房很远的海内的任意一个中央,对业务也毫无影响(AB机房地区间隔很长,如果无奈做到自闭环,则互相调用的RT会变长,必然影响业务),那么你就能够认为是单元化胜利了。

单元化流量如下:

单元化做双活只须要在底层的数据层面进行同步即可。如下所示:

双活的流量路由规定

路由形式

随机路由

将流量依照比例随机路由到各自IDC,只需依照比例路由到每个IDC,而无任何规定。故障状况下,能够将该故障机房的流量切换到另外的IDC。

用户id路由

依据用户id将流量依照肯定比例路由到各自IDC,每个用户的操作都会路由到指定的IDC。故障状况下,能够将该故障机房的流量依照用户切换到另外的IDC。

地区路由

依照用户所属城市将流量依照肯定比例路由到各自的IDC,每个中央的用户操作都会路由到指定的IDC。故障状况下,能够将该故障机房的流量地区切换到另外的IDC。

四轮出行的抉择

通过多番探讨,哈啰四轮出行最终抉择了依照地区路由。

次要理由如下:随机路由在各类多活设计中都不算一个好的计划,次要起因是随机路由因为其无规律性,在多活我的项目中,无奈做到单元化。抉择地区路由而非用户维度路由,次要是因为四轮业务和电商业务存在一些区别,在电商业务中的基本操作都是基于C端用户,每个C端用户只操作本人的订单数据,因而订单数据依照用户id人造是隔离的,单元化也比拟好做,然而此计划也是就义了B端的商家的体验,商家操作多用户订单数据必然会存在跨机房的可能性,从而影响商家体验。

作为四轮来说,买家和卖家别离为乘客和司机,是人造的双订单模型(司机订单和乘客订单),因而如果用用户id路由,则在同时操作司机订单和乘客的接口(如司机接单)中,必然会存在大量的跨机房路由(司机和乘客因为用户id不同分到不同的机房)。而如果依照地区来分,则因为出行订单跨城或者跨省的概率极低,因而该跨机房率会大大降低,且能够依据理论跨机房单量比例去人为升高跨机房数量。然而该计划也有肯定缺点,因为地区订单会在不同的工夫和场景下,如:节假日、下雨天等会存在比拟大的流量稳定,导致同城、同省流量稳定较大,从而导致机房压力大小不统一。

双活计划

两头计划


双活中间件提供的能力次要分为四类,存储、音讯、soa和雪花算法。

存储

存储提供的能力大部分为底层的数据双向同步。
redis的跨机房读写和跨机房加锁均是因为双订单模型无奈做到单元化,提供的双活能力。
redis双写则为无双向同步能力时的长期能力。
db纠偏则是db层面指定路由,也是为了兜底,当soa路由出异样,在db层做最初的兜底(可拜访跨机房数据)。
db禁写爱护则是当业务开启禁写爱护,非本机房的订单无奈在本订单操作,也是db兜底爱护的一种。

音讯

音讯则分为发送和生产。
对于发送来说,单元到核心的复制和核心到单元的复制,则都是一个机房音讯复制到另外机房,也是无奈单元化的一种解决方案。当然该计划也能够兼容双活利用发送音讯和非双活利用消费者的问题。
生产本机房:只能生产本机房产生的音讯,异地机房的复制音讯无奈生产。
都不生产:代表本机房和异地机房都不生产。
生产本机房和异地机房音讯,则代表音讯生产本机房和异地机房音讯(生产双份音讯)。

soa

soa接口须要依据特定的条件将rpc申请路由到失常的机房。
服务提供方路由则示意该路由规定由服务提供方指定。
服务生产方路由则示意该路由规定由服务生产方指定。

雪花算法

双活因为zk集群是两个机房的,须要在雪花算法上打上机房标识,保障全局惟一。

业务革新


业务革新大部分是基于中间件计划的革新。而其中的局部计划是基于业务本人述求进行的一些双活革新点。

单元化革新:局部业务逻辑之前在单机房状况下无奈做到单元化,须要对局部可单元化的业务进行革新。

db缓存一致性:则是基于订单可靠性保障,对订单数据通过binlog音讯保障两机房数据一致性。

机房过滤革新:基于机房信息,解决非本机房逻辑,或者过滤非本机房逻辑(目前无奈单元化的长期计划)。

单号革新:发单的时候须要将路由规定打到订单号上,在批改订单其余属性时依据订单号进行路由(保障单元化)。

(本文作者:柳健强)

本文系哈啰技术团队出品,未经许可,不得进行商业性转载或者应用。非商业目标转载或应用本文内容,敬请注明“内容转载自哈啰技术团队”。