看完这篇异地多活的改造,我决定和架构师battle一下|得物技能

源码 2024-9-13 05:09:26 66 0 来自 中国
文|尹吉欢 得物技能
1. 简述

异地多活的概念以及为什么要做异地多活这里就不举行概述了。概念性的很多,像什么同城双活、两地三中央、三地五中央等等概念。假如有对这些容灾架构模式感爱好的可以阅读下这篇文章举行相识:《浅谈业务级灾备的架构模式》。
阅读本篇文章之前,我们先明确一下配景,如许各人后续在看的时间就不会产生狐疑。
1.1 机房分别

得物多活改造一期现在有两个机房,分别是机房A和机房B。文章中大部门图中都会有标识,这就分析是两个差别的机房。
A机房我们界说为中央机房,也就是多活上线之前正在利用的机房。假如说到中央机房那指的就是A机房。另一个B机房,在形貌的时间大概会说成单元机房,那指的就是B机房。
1.2 单元化

单元化简单点我们直接就可以以为是一个机房,在这个单元内可以大概完成业务的闭环。比如说用户进入APP,欣赏商品,选择商品确认订单,下单,付出,检察订单信息,这整个流程都在一个单元中可以大概完成,而且数据也是存储在这个单元内里。
做单元化无非就两个缘故起因,容灾和进步体系并发本事。但是也得思量机房创建的规模和技能,硬件等投入的本钱。具体的就不多讲了,各人大概明确了就行。
2. 改造点

相识改造点之前我们先来看下现在单机房的近况是什么样子,才华更好地资助各人去明确为什么要做这些改造。

1.png 如上图所示,客户端的哀求进来会先到SLB(负载平衡),然后到我们内部的网关,通过网关再分发到具体的业务服务。业务服务会依赖Redis、Mysql、 MQ、Nacos等中心件。
既然做异地多活,那么肯定是在差别地区有差别的机房,比如中央机房,单元机房。以是我们要实现的结果如下图所示:
各人看上面这张图大概会感觉很简单,实在也就是一些常用的中心件,再多一个机房摆设罢了,这有什么难度。假如你如许想我只能说一句:格局小了啊
2.1 流量调治

用户的哀求,从客户端发出,这个用户的哀求该到哪个机房,这是我们要改造的第一个点。
没做多活之前,域名会剖析到一个机房内,做了多活后,域名会随机剖析到差别的机房中。假如按照这种随机的方式是肯定有题目的,对于服务的调用是无所谓的,由于没有状态。但是服务内部依赖的存储是有状态的呀。
我们是电商业务,用户在中央机房下了一个单,然后跳转到订单详情,这个时间哀求到了单元机房,底层数据同步有延长,一访问报个错:订单不存在。用户就地就懵了,钱都付了,订单没了。
以是针对同一个用户,尽大概在一个机房内完成业务闭环。为了办理流量调治的题目,我们基于OpenResty二次开发出了DLB流量网关,DLB会对接多活控制中央,可以大概知道当前访问的用户是属于哪个机房,假如用户不属于当前机房,DLB会直接将哀求路由到该用户所属机房内的DLB。
3.png 假如每次都随机到固定的机房,再通过DLB去校正,肯定会存在跨机房哀求,耗时加长。以是在这块我们也是联合客户端做了一些优化,在DLB校正哀求后,我们会将用户对应的机房IP直接通过Header相应给客户端。如许下次哀求的时间,客户端就可以直接通过这个IP访问。
假如用户当前访问的机房挂了,客户端必要降级成之前的域名访问方式,通过DNS剖析到存活的机房。
2.2 RPC框架

当用户的哀求到达了单元机房内,理论上后续全部的利用都是在单元机房完成。前面我们也提到了,用户的哀求只管在一个机房内完成闭环,只是只管,没有说全部。
这是由于有的业务场景不恰当分别单元,比如库存扣减。以是在我们的分别内里,有一个机房是中央机房,那些不做多活的业务只会摆设在中央机房内里,那么库存扣减的时间就必要跨机房调用。
哀求在中央机房,怎么知道单元机房的服务信息?以是我们的注册中央(Nacos)要做双向同步,如许才华拿到全部机房的服务信息。
当我们的注册信息采取双向复制后,对于中央服务,直接跨机房调用。对于单元服务会存在多个机房的服务信息,假如不举行控制,则会出现调用其他机房的情况,以是RPC框架要举行改造。
2.2.1 界说路由范例

(1)默认路由
哀求到中央机房,会优先调用中央机房内的服务,假如中央机房无此服务,则调用单元机房的服务,假如单元机房没有此服务则直接报错。
(2)单元路由
哀求到单元机房,那么分析此用户的流量规则是在单元机房,接下来全部的RPC调用都只会调用单元机房内的服务,没有服务则报错。
(3)中央路由
哀求到单元机房,那么直接调用中央机房的服务,中央机房没有服务则报错。哀求到中央机房,那么就本机房调用。
2.2.2 业务改造

业务方必要对自己的接口(Java interface)举行标志是什么范例,通过@HARoute加在接口上面。标志完成后,在Dubbo接口举行注册的时间,会把路由范例放入到这个接口的元数据内里,在Nacos背景可以检察。反面通过RPC调用接口内部全部的方法都会按照标志范例举行路由。
假如标志为单元路由,现在我们内部的规范是方法的第一个参数为小写的long buyerId,RPC在路由的时间会根据这个值判定用户地点的机房。
路由逻辑如下:
5.png 2.2.3 改造过程


  • 接口复制一份,定名为UnitApi,第一个参数加long buyerId。在新接口的实现内里调用老接口,新旧接口共存。
  • 将UnitApi发布上线,此时没有流量。
  • 业务方必要升级其他域的API包,将老接口的调用切换为新的UnitApi,此处增长开关控制。
  • 上线后,通过开关控制调用走UnitApi,有题目可关闭开关。
  • 下线老的API,完成切换。
2.2.4 碰到的题目

2.2.4.1 其他场景切单元接口

除了RPC直接调用的接口,另有一大部门是通过Dubbo泛化过来的,这块在上线后也必要将流量切到UnitApi,等老接口没有哀求量之后才华下线。
2.2.4.2 接口分类

接口举行分类,之前没有多活的束缚,一个Java interface中的方法大概各种各样,假如现在你的interface为单元路由,那么内里的方法第一个参数都必须加buyerId,其他没有buyerId场景的方法要挪出去。
2.2.4.3 业务层面调解

业务层面调解,比如之前查询订单只必要一个订单号,但是现在必要buyerId举行路由,以是接入这个接口的上游都必要调解。
2.3 数据库

哀求顺遂的到达了服务层,接下来要跟数据库打交道了。数据库我们界说了差别的范例,界说如下:
(1)单元化
此库为单元库,会同时在两个机房摆设,每个机房都有完整的数据,数据采取双向同步。
(2)中央化
此库为中央库,只会在中央机房摆设。
(3)中央单元化
此库为中央单元库,会同时在两个机房摆设,中央可以读写,其他机房只能读。中央写数据后单向复制到另一个机房。
2.3.1 署理中心件

现在各个业务方用的都是客户端情势的Sharding中心件,每个业务方的版本还差别等。在多活切流的过程中必要对数据库禁写来保证业务数据的正确性,假如没有同一的中心件,这将是一件很贫苦的事变。
以是我们通过对ShardingSphere举行深度定制,二次开发数据库署理中心件 彩虹桥。各业务方必要接入彩虹桥来更换之前的Sharding方式。在切换过程中,怎样保证稳固平滑迁移,出题目怎样快速恢复,我们也有一套乐成的实践,各人可以看下我之前写的这篇文章《客户端分片到Proxy分片,如丝般顺滑的安稳迁移》,内里有实现方式。
6.png 2.3.2 分布式ID单元化的库,数据层面会做双向同步复制利用。假如直接用表的自增ID则会出现下面的辩说题目:

这个题目可以通过设置差别机房有差别的自增步长来办理,比如中央机房的自增步长为奇数,单元机房的自增步长为偶数。但比力贫苦,后续大概会增长更多的机房。我们采取了一种一劳永逸的方式,接入全局唯一的分布式ID来制止主键的辩说。
2.3.2.1 客户端接入

现在,接入分布式ID有两种方式,一种是应用内通过根本架构提供的jar包接入,具体逻辑如下:
7.png 2.3.2.2 彩虹桥接入

另一种就是在彩虹桥中对具体的表设置ID的天生方式,支持对接分布式ID服务。
2.3.3 业务改造

2.3.3.1 单元化库写哀求必须携带ShardingKey

在Dao层对表举行利用的时间,会通过ThreadLocal设置当火线法的ShardingKey,然后通过Mybatis拦截器机制,将ShardingKey通过Hint的方式放入SQL中,带给彩虹桥。彩虹桥会判定当前的ShardingKey是否属于当前机房,假如不是直接禁写报错。
这里跟各人简单的分析下为什么切流过程中要禁写,这个实在跟JVM的垃圾接纳有点相似。假如不对利用禁写,那么就会不停的产生数据,而我们切流,肯定要保证当前机房的数据全部同步已往了之后才开始见效流量规则,否则用户切到另一个机房,数据没同步完,就会产生业务题目。除了彩虹桥会禁写,RPC框架内部也会根据流量规则举行阻断。
2.3.3.2 数据库毗连指定毗连模式

毗连模式的界说有两种,分别是中央和单元。
假如应用的数据源指定了毗连模式为中央,那么在中央机房可以正常初始化数据源。在单元机房不会初始化数据源。
假如应用的数据源指定了毗连模式为单元,那么在中央机房和单元机房都可以正常初始化数据源。
这里表明下为什么要有毗连模式这个计划?
在我们的项目中,会出现同时毗连2个库的情况,一个单元库,一个中央库。假如没有毗连模式,上层代码是一份,这个项目会在中央和单元两个机房同时摆设,也就是两个地方都会去创建数据源。
但实际上,我的中央库只必要在中央机房毗连就可以了,由于中央库全部的利用都是中央接口,流量必定会走中央,我在单元机房去毗连是没故意义的。另一个题目就是我不必要在单元机房维护中央库的数据库信息,假如没有毗连模式,那么单元机房的彩虹桥也必须要有中央库的信息,由于项目会举行毗连。
2.3.4 碰到的题目

2.3.4.1 单元接口中不能访问中央数据库

假如接口标志成了单元接口,那么只能利用单元库。在从前没有做多活改造的时间,根本上没有什么中央和单元的概念,全部的表也都是放在一起的。多活改造后,我们会根据业务场景对数据库举行分别。
分别后,中央库只会被中央机房的步调利用,在单元机房是不答应毗连中央库。以是单元接口内里假如涉及到对中央库的利用,必定会报错。这块必要调解成走中央的RPC接口。
2.3.4.2 中央接口不能访问单元数据库

跟上面同样的题目,假如接口是中央的,也不能在接口内里利用单元库。中央接口的哀求都会强制走到中央机房,假如内里有涉及到另一个机房的利用,也必须走RPC接口举行精确的路由,由于你中央机房不能利用另一个机房的数据库。
2.3.4.3 批量查询调解

比如批量根据订单号举行查询,但是这些订单号不是同一个买家。假如任意用一个订单的买家作为路由参数,那么其他一些订单实在是属于另一个单元的,如许就有大概存在查询到旧数据的题目。
如许批量查询的场景,只能针对同一个买家可用,假如是差别的买家必要分批调用。
2.4 Redis

Redis在业务中用的比力多,在多活的改造中也有很多地方必要调解。对于Redis起首我们明确几个界说:
不做双向同步
Redis不会和数据库一样做双向同步,也就是中央机房一个Redis集群,单元机房一个Redis集群。每个机房的集群中只存在一部门用户的缓存数据,不是全量的。
Redis范例
Redis分为中央和单元,中央只会在中央机房摆设,单元会在中央和单元两个机房摆设。
2.4.1 业务改造

2.4.1.1 Redis多数据源支持

多活改造之前,每个应用都有一个单独的Redis集群,多活改造后,由于应用没有举行单元化和中央的拆分,以是一个应用中会存在必要毗连两个Redis的情况。一个中央Redis,一个单元Redis。
根本架构提供的Redis包必要支持多数据源的创建,而且界说通用的设置格式,业务方只必要在自己 的设置内里指定集群和毗连模式即可完成接入。此处的毗连模式跟数据库的同等。
具体的Redis实例信息会在设置中央同一维护,不必要业务方关心,如许在做机房扩容的时间,业务方是不必要调解的,设置如下:
spring.redis.sources.carts.mode=unit spring.redis.sources.carts.cluster-name=cartsCuster同时我们在利用Redis的时间要指定对应的数据源,如下:
@Autowired @Qualifier(RedisTemplateNameConstants.REDIS_TEMPLATE_UNIT) private RedisTemplate<String, Object> redisTemplate;2.4.1.2 数据同等性

数据库缓存场景,由于Redis不会双向同步,就会存在数据的差别等性题目。比如用户一开始在中央机房,然后缓存了一份数据。举行切流,切到单元机房,单元机房又缓存了一份数据。再举行切回中央机房的利用,此时中央机房里的缓存是旧的数据,不是最新的数据。
以是在底层数据变动的时间,我们必要对缓存举行失效利用,如许才华保证数据的终极同等性。单纯依赖缓存的失效时间来到达同等性不是一个合适的方案。
这里我们的方案是采取订阅数据库的binlog来举行缓存的失效利用,可以订阅本机房的binlog,也可以订阅其他机房的binlog来实现全部机房的缓存失效。
2.4.2 碰到的题目

2.4.2.1 序列化协议兼容

在接入新的Redis Client包后,测试情况出现了老数据的兼容题目。大部门应用都没题目,有个别应用固然用了同一的底层包,但是自己定制了序列化方式,导致Redis按新的方式装配后没有效到自界说的协议,这块也是举行了改造,支持多数据源的协议自界说。
2.4.2.2 分布式锁的利用

现在项目中的分布式锁是基于Redis实现,当Redis有多个数据源之后,分布式锁也必要举行适配。在利用的地方要区分场景,默认都是用的中央Redis来加锁。
但是单元接口内里的利用都是买家场景,以是这部门必要调解为单元Redis锁对象举行加锁,如允许以大概进步性能。其他的一些场景有涉及到全局资源的锁定,那就用中央Redis锁对象举行加锁。
2.5 RocketMQ

哀求到达服务层后,跟数据库和缓存都举行了交互,接下来的逻辑是要发一条消息出去,其他业务必要监听这个消息做一些业务处置惩罚。
假如是在单元机房发出的消息,发到了单元机房的MQ中,单元机房的步调举行消耗,是没有题目的。但假如中央机房的步调要消耗这个消息怎么办?以是MQ跟数据库一样,也要做同步,将消息同步到另一个机房的MQ中,至于另一个机房的消耗者要不要消耗,这就要让业务场景去决定。
2.5.1 界说消耗范例

2.5.1.1 中央订阅

中央订阅指的是消息无论是在中央机房发出的还是单元机房发出的,都只会在中央机房举行消耗。假如是单元机房发出的,会将单元的消息复制一份到中央举行消耗。
2.5.1.2 寻常订阅

寻常订阅就是默认的活动,指的是就近消耗。在中央机房发送的消息就由中央机房的消耗者举行消耗,在单元机房发送的消息就由单元机房的消耗举行消耗。
2.5.1.3 单元订阅

单元订阅指的是消息会根据ShardingKey举行消息的过滤,无论你在哪个机房发送消息,消息都会复制到另一个机房,此时两个机房都有该消息。通过ShardingKey判定当前消息应该被哪个机房消耗,符合的才会举行消耗,不符合的框架层面会自动ACK。
2.5.1.4 全单元订阅

全单元订阅指的是消息无论在哪个机房发出,都会在全部的机房举行消耗。
2.5.2 业务改造

2.5.2.1 消息发送方调解

消息发送方,必要联合业务场景举行区分。假如是买家场景的业务消息,在发消息的时间必要将buyerId放入消息中,具体怎么消耗由消耗方决定。假如消耗方是单元消耗的话那么必须依赖发送方的buyerId,否则无法知道当前消息应该在哪个机房消耗。
2.5.2.2 消息消耗方指定消耗模式

前面提到了中央订阅,单元订阅,寻常订阅,全单元订阅多种模式,到底要怎么选就是要联合业务场景来定的,定好后在设置MQ信息的时间指定即可。
比如中央订阅就恰当你整个服务都是中央的,其他机房都没摆设,这个时间肯定恰当中央订阅。比如你要对缓存举行扫除,就比力恰当全单元订阅,一旦数据有变动,全部机房的缓存都清撤消。
2.5.3 碰到的题目

2.5.3.1 消息幂等消耗

这个点实在根据多活没有多大关系,就算不做多活,消息消耗场景,肯定是要做幂等处置惩罚的,由于消息自己就有重试机制。单独拎出来说是由于在多活场景下除了消息自己的重试会导致消息重复消耗,别的在切流的过程中,属于切流这部门用户的消息会被复制到另一个机房重新举行消耗,在重新消耗的时间,会基于时间点举行消息的重新投放,以是有大概会消耗到之前已经消耗了的消息,这点必须留意。
再表明下为什么切流过程中会有消息消耗失败以及必要复制到另一个机房行止置惩罚,如下图所示:
用户在当前机房举行业务利用后,会产生消息。由于是单元订阅,以是会在当前机房举行消耗。消耗过程中,发生了切流利用,消耗逻辑内里对数据库举行读写,但是单元表的利用都携带了ShardingKey,彩虹桥会判定ShardingKey是否符合当前的规则,发现不符合直接禁写报错。这批切流用户的消息就全部消耗失败。比及流量切到另一个机房后,假如不举行消息的重新投递,那么这部门消息就丢失了,这就是为什么要复制到另一个机房举行消息的重新投递。
2.5.3.2 切流场景的消息次序题目

上面讲到了在切流过程中,会将消息复制到另一个机房举行重新消耗,然后是基于时间点去回放的,假如你的业务消息自己就是寻常的Topic,在消息回放的时间假犹如一个场景的消息有多条,这个次序并不愿定是按照之前的次序来消耗,以是这里涉及到一个消耗次序的题目。
假如你之前的业务场景自己就是用的次序消息,那么是没题目的,假如之前不是次序消息,这里就有大概有题目,我举个例子分析下:
有个业务场景,触发一次功能就会产生一条消息,这个消息是用户级别的,也就是一个用户会产生N条消息。消耗方会消耗这些消息举行存储,不是来一次消息就存储一条数据,而是同一个用户的只会存储一条,消息内里有个状态,会根据这个状态举行判定。
比如下面的消息统共投递了3条,按正常次序消耗终极的结果是status=valid。
10:00:00  status=valid 10:00:01  status=invalid 10:00:02  status=valid假如消息在另一个机房重新投递的时间,消耗次序酿成了下面如许,终极结果就是status=invalid。
10:00:00  status=valid 10:00:02  status=valid 10:00:01  status=invalid办理方案有下面几种:

  • Topic换成次序消息,以用户举行分区,如许就能保证每个用户的消息严酷按照发送次序举行消耗。
  • 对消息做幂等,已消耗过就不再消耗。但是这里跟寻常的消息差别,会有N条消息,假如对msgId举行存储,如许就可以判定是否消耗过,但是如许存储压力太大,固然也可以只存储近来N条来减小存储压力。
  • 消息幂等的优化方式,让消息发送方每发送一次,都带一个version,version必须是递增。消耗方消耗消息后把当前version存储起来,消耗之前判定消息的version是否大于存储的version,满足条件才举行消耗,如许既制止了存储的压力也能满足业务的需求。
2.6 Job

Job在我们这边用的不多,而且都是老的逻辑在用,只有几个破晓统计数据的任务,新的都接入了我们自研的TOC(超时中央)来管理。
2.6.1 业务改造

2.6.1.1 中央机房执行

由于Job是老的一套体系,现在也只有个位数的任务在执行,以是在底层框架层面并没有支持多活的改造。后续会将Job的逻辑迁移到TOC中。
以是我们必须在业务层面举行改造来支持多活,改造方案有两种,分别介绍下:
(1)两个机房同时执行Job,数据处置惩罚的时间,比如处置惩罚用户的数据,通过根本架构提供的本事,可以判定用户是否属于当前机房,假如数据就执行,否则就跳过这条数据。
(2)从业务场景出发,Job都是破晓去执行的,不属于在线业务,对数据同等性要求没那么高。纵然不按单元化行止置惩罚数据,也没什么题目。以是只必要在中央机房执行Job即可,另一个机房我们可以通过设置让Job任务不举行见效。
但是这种方式必要去梳理Job里的数据利用,假如有对中央库利用的,没关系,自己就是在中央机房跑。假如有对单元库利用的,必要调解为走RPC接口。
2.7 TOC

TOC是我们内部用的超时中央,当我们有需求必要在某个时间点举行触发业务动作的时间都可以接入超时中央来处置惩罚。
举个例子:订单创建后,N分钟内没有付出就自动取消。假如业务方自己实现,要么定时扫表举行处置惩罚,要么用MQ的延长消息。有了TOC后,我们会在订单创建之后,往TOC注册一个超时任务,指定某个时间点,你要回调我。在回调的逻辑逻辑里去判定订单是否已完成付出,假如没有则取消。
2.7.1 业务改造

2.7.1.1 任务注册调解

在注册超时中央任务的时间,业务方必要辨认任务是否要符合单元化的尺度。假如此任务只是对中央数据库举行利用,那么这个任务回调在中央机房即可。假如此任务是对单元数据库利用,那么在注册任务的时间就必要指定buyerId,超时中央在触发回调的时间会根据buyerId举行路由到用户所属机房举行处置惩罚。
现在超时中央是只会在中央机房举行摆设,也就是全部的任务都会在中央机房举行调治。假如任务注册的时间没有指定buyerId,超时中央在回调的时间就不知道要回调哪个机房,默认回调中央机房。要想让超时中央根据多活的路由规则举行回调,那么注册的时间必须指定buyerId。
3. 服务分别

阅读完上面的改造内容,信赖各人另有一个迷惑点就是我的服务该怎么分别呢?我要不要做单元化呢?
3.1 团体方向

起首要根据整个多活的一个团体目标和方向去梳理,比如我们的团体方向就是买家生意业务的焦点链路必须实现单元化改造。那么这整个链路全部依赖的上卑鄙都必要改造。
用户欣赏商品,进入确认订单,下单,付出,查询订单信息。这个焦点链路实在涉及到了很多的业务域,比如:商品,出价,订单,付出,商家等等。
在这些已经明确了的业务域下面,大概另有一些其他的业务域在支持着,以是要把团体的链路都梳理出来,一起改造。固然也不是全部的都必须做单元化,还是得看业务场景,比如库存,肯定是在生意业务焦点链路上,但是不必要改造,必须走中央。
3.2 服务范例

3.2.1 中央服务

中央服务只会在中央机房摆设,而且数据库也肯定是中央库。可以对整个应用举行打标成中央,如许外部访问这个服务的接口时都会被路由到中央机房。
3.2.2 单元服务

单元服务会在中央机房和单元机房同时摆设,而且数据库也肯定是单元库。单元服务是买家维度的业务,比如确认订单,下单。
买家维度的业务,在接口界说上,第一个参数必须是buyerId,由于要举行路由。用户的哀求已经根据规则举行分流到差别的机房,只会利用对应机房内里的数据库。

3.2.3 中央单元服务

中央单元服务也就是说这个服务内里既有中央的接口也有单元的接口。而且数据库也是有两套。以是这种服务实在也是要在两个机房同时摆设的,只不过是单元机房只会有单元接口过来的流量,中央接口是没有流量的。
一些底层的支持业务,比如商品,商家这些就属于中央单元服务。支持维度的业务是没有buyerId的,商品是通用的,并不属于某一个买家。
而支持范例的业务底层的数据库是中央单元库,也就是中央写单元读,写哀求是在中央举行,比如商品的创建,修改等。利用后会同步到另一个机房的数据库内里。如许的长处就是可以镌汰我们在焦点链路中的耗时,假如商品不做单元化摆设,那么欣赏商品大概下单的时间查询商品信息都必须走中央机房举行读取。而现在则会就近路由举行接口的调用,哀求到中央机房就调中央机房的服务,哀求到单元机房就调单元机房的服务,单元机房也是有数据库的,不必要跨机房。
13.png 从久远思量,还是必要举行拆分,把中央的业务和单元的业务拆开,如许会比力清晰。对于反面新同砚在界说接口,利用数据库,缓存等都有长处,由于现在是混淆在一起的,你必须要知道当前这个接口的业务属于单元还是中央。
拆分也不是绝对的,还是那句话得从业务场景出发。像订单内里的买家和卖家的业务,我以为可以拆分,后续维护也比力方便。但是像商品这种,并不存在两种脚色,就是商品,对商品的增编削成在一个项目中也方便维护,只不过是要举行接口的分类,将新增,修改,删除的接口标志为中央。
4. 切流方案

前面我们也提到了再切流过程中,会禁写,会复制MQ的消息到另一个机房重新消耗。接下来给各人介绍下我们的切流方案,可以大概资助各人更深刻的明确整个多活的非常场景下处置惩罚流程。
(1)下发禁写规则
当必要切流的时间,利用职员会通过双活控制中央的背景举行利用。切流之前必要先举行已有流量的清算,必要下发禁写规则。禁写规则会下发到中央和单元两个机房对应的设置中央内里,通过设置中央去关照必要监听的步调。
(2)彩虹桥执行禁写逻辑
彩虹桥会用到禁写规则,当禁写规则在设置中央修改后,彩虹桥能立马感知到,然后会根据SQL中携带的shardingkey举行规则的判定,看当前shardingkey是否属于这个机房,假如不属于则举行拦截。
(3)反馈禁写见效结果
当设置变动后会推送到彩虹桥,设置中央会感知到设置推送的结果,然后将见效的结果反馈给双活控制中央。
(4)推送禁写见效时间给Otter
双活控制中央收到全部的反馈后,会将全部见效的时间点通过MQ消息告诉Otter。
(5)Otter举行数据同步
Otter收到消息会根据时间点举行数据同步。
(6)Otter同步完成反馈同步结果
见效时间点之前的数据全部同步完成后会通过MQ消息反馈给双活控制中央。
(7)下发最新流量规则
双活中央收到Otter的同步完成的反馈消息后,会下发流量规则,流量规则会下发到DLB,RPC,彩虹桥。
后续用户的哀求就会直接被路由到精确的机房。
5. 总结

信赖各人看了这篇文章,对多活的改造应该有了肯定的相识。固然本篇文章并没有把全部多活干系的改造都表明清晰,由于整个改造的范围着实是太大了。本篇紧张讲的是中心件层面和业务层面的一些改造点和过程,同时另有其他的一些点都没有提到。比如:机房网络的创建、发布体系支持多机房、监控体系支持多机房的整个链路监控,数据巡检的监控等等。
多活是一个高可用的容灾手段,但实现的本钱和对技能团队的要求非常高。在实现多活的时间,我们应该联合业务场景去举行计划,不是全部体系,全部功能都要满足多活的条件,也没有100%的可用性,有的只是在极度场景下对业务的一些弃取罢了,优先保证焦点功能。
以上就是我们在多活改造中的一些履历,分享出来渴望可以对正在阅读的你有一些资助。
*文/尹吉欢
关注得物技能公众号,每周一三五晚18:30更新技醒目货
要是以为文章对你有资助的话,欢迎批评转发点赞~
限时活动:
克日起至5月31日20:00,公开转发得物技能恣意一篇文章到朋侪圈,就可以在「得物技能」公众号背景复兴「得物」,加入得物文化衫抽奖。
活动保举:
直播主题:Golang微服务专场-得物技能沙龙2万人都在看的沙龙是什么样的呢?必要PPT的话,得物技能公众号背景复兴「PPT」可以领取合集。
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-11-22 23:00, Processed in 0.182933 second(s), 35 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表