00:00
接下来我们就来说一下分布式事务,首先我们说为什么会有分布式事务,我们还是以我们之前的下单场景为例,比如我们来看这张图,这张图呢,跟我们之前的下单场景稍微不一样,我们就以它为例,那现在呢,有一个业务叫下单,我们的business这个业务是下单,然后呢,他首先要调用我们三个功能,第一个是我们扣库存,我们这个减库存,然后呢,接下来是我们来下订单,相当于保存订单,订单保存完了,我们可能还要扣减积分,所以我们只有这三个我们同时调用成功了,我们这个单才算是下成功。那如果是我们以前的单体应用,我们将这三处代码呢,全部写在一个系统里边,而且我们全部联想的是一个数据库,那这样的话,我们使用本地事物就可以非常方便的控制住,只要有一个失败,大家全体回滚。但是呢,正是由于我们分布式系统的出现,由于我们这个业务太大,我们不可能将所有业务全写。
01:00
一个项目里边,所以我们拆分成了好多微服务,比如我们的库存服务,我们的订单服务,还有我们的用户账户服务,那现在拆分了三个服务,而且呢,每个服务还是连自己的数据库操作,自己的数据还互相没有关系,再加上我们分布式系统之间,我们部署呢,还可能不在一块儿,比如我们这个库存服务在一号机器,订单在二号,然后我们的账号在三号机器,那这样我们想要完成整个下单逻辑,我们就要远程调用这三个机器的各个方法,但是又由于我们分布式系统中经常会出现我们一些异常,比如我们这个机器宕机,我们二号执行完了,想要调用我们这个三号业务,但是三号业务呢,这个机器宕机了,那一宕机以后呢,会出现一个什么问题,我们其实呢是二号,他不能感知到我们这个三号到底是执行成了还是败了,如果是我们在二号掉三号之前他给炸了,那还好我们二号知道他连不上。
02:00
放三号那把自己也回滚一下,但是呢,如果是我们二号掉了,三号机器的代码有请求给他发过去了,然后三号机器代码可能都执行完了,正好在执行完的那一刻就要给他返回的时候,他给炸了,那这样的话呢,我们二号机器相当于永远等不到它的返回,认为他呢也宕机了,但是此时二号机器他是没办法知道我们三号机器到底是执行成了还是执行败了,就算我们去要查三号机器成了还是败了,他都宕机了,所以呢,我们现在可能会由于机器宕机的问题,我们想要同步,他们之间的状态不好同步,因为我们想要让一个失败大家全体失败来做一个事务,或者呢,由于网络异常,比如三号机器呢,一切都执行成功了,然后呢,把所有的成功消息带给我们订单服务给他返回了,结果呢,我们消息刚发出去,老鼠把网线咬断了,诶那这个我们这个消息传不出去了,怎么办?所以呢,现在我们这个二号还是不知道我们这个三号机器它到底。
03:00
你执行的状态怎么样,那他们三个呢,就无法同步我们的事务状态,再加上我们分布式系统里边,如果引入了更多中间件,一些消息中间件造成的丢失、乱序,包括一些数据的发送错误,我们经常类型转换,转成了这个控制针异常的类型转不过来的,但实际人家远程执行成功了,只是你业务代码出了问题,还有我们一些不可靠的这些网络TCP连接等等等等,只要是我们这些网络的问题,节点故障的问题,我们机器服务节点故障的问题,都会导致我们某一个机器的状态,它的这个成功失败,别的机器呢,可能没办法感知,那这样呢,想要做我们整个事物,在分布式系统里边想协调一号、二号、三号机器,他们整体要么都回滚,要么都成功,这就非常难,那这个呢,就是我们的分布式事务,只要我们有微服务,我们的业务太大,我们拆成微服务部署在了不同机器,那我们在。
04:00
后来的业务开发中,我们一定百分百避免不了我们的分布式失误,这个东西呢,就是躲得过初一,躲不过失误,我们可以提前设计一些,比如我们前几个业务呢,我们通过自己的设计,我们把数据库揉在一起,或者怎么着我们终于躲过了分布式事务,但在后边一些复杂的业务又出现远程调用,我们总是躲不过,我们不可能将所有的代码全部放在一个项目里边,因为现在的项目呢,规模都太大了。没有任何机器能负担住我们一个大型项目的运行,所以只要是微服务架构,我们的分布式事务是无法避免的,那我们该如何解决分布式事务?分布式事物出现的原因就是我们节点之间互相的状态不能同步,包括网络状况问题,我们这些数据呢互相感知不到,那现在我们就希望有人能协调这个事情,当然我们做这个之前,我们先来考虑一下我们分布式系统里边的一些定理,它既然能叫定理,就是我们不能打破的一个理论。那我们在分布式系统里边有一个叫CP原则,也叫CP定理,CP指的是什么?CP指的是我们一致性、可用性和分区容错性,C就是我们说的一致性,它的首字母以及可用性,P呢就是我们分区容错性,那CP想说一件什么事情,他想说咱们这个分布式系统里边,比如我们这三个节点一号。
05:29
二号三号节点,那么现在呢,想要做一个事物,想成功都成功,想失败都失败,或者呢,我保存了一个值,那大家伙呢,都得跟我一样,所以我们说的第一个一致性指的就是这个在我们分布式系统里边,比如我们这123号机器,假设我们都是数据库,想要保存一个数据,比如这个数字呢是八,那我们既然要保存八,那一号保存了八,我们下一个请求可能要访问二号数据库。二号呢就也得有八,三号呢就也得有八,所以呢,相当于我们一个分布式系统里边所有这个数据的备份,比如我们准备把八号备份在三个机器里边,所有数据的这个备份在同一个时刻是否都有同样的值,比如我一号机器,我说诶八成功了,那你再来访问二号机器,结果你拿的刚才数据是七,那这个呢就不一致了。所以我们说的一致性就是分布式系统里面所有的数据备份在同一时刻是一样的。还有我们的可用性,可用性就指的是我们一号机器,二号机器和三号机器,如果有一个机器完蛋了,我们整个集群还能不能响应客户端的所有操作,假设能响应,那就说明是可用的,如果不能响应。
06:43
只要有任何一个机器炸了,我们呢,就不响应客户端的操作,说诶我们这个后台集群有问题,有一个人坏了,等我们修好了你再来操作。这就是不可用的,然后还有分区容错,分区容错指的就是我们一号机器,二号机器,三号机器,由于他们部署在不同节点,肯定呢他们之间通信要使用这个网络,我们网络呢,肯定会出现我们的一些通信失败错误问题,只要通信失败,我们就说我们这个分区呢,发生了这个错误,错误的话我们接下来该怎么办?但我们现在呢,能发现一件事,就是呢,如果我们这个一致性、可用性和分区容错性,CP告诉我们的是这三个不能三者兼顾,为什么?我来举一个例子,假设一致性一、233个机器都想要保存八号数据,我们一个请求过来,让它三个备份节点同时都要把八号数据保存起来,所以呢,如果我们想要满足一致性C,那我们现在呢,三个机器全部都保存好了,那么接下来在可用性和分区容错二选一,怎么叫分区容错二选一,假设我。
07:52
我们不是由于节点故障,而是由于通信故障,我们一号跟三号机器的网线断了,我们保存数据呢,肯定只给某一个机器发了请求,我给一号机器发了八请求,然后呢,一号机器让二号机器同步了一下,诶它也保存了八,结果让三号机器同步的时候,由于网线断了,他呢死活连不到三号机器,那此时呢,我们就发生了我们的分区错误,我们这个网络出错了,就是我们分区容错了,那们分区错误以后呢,接下来我们就要考虑我们能不能满足可用性呢,假设我们还让它满足可用性,行,我们让它三个机器呢都能用,那下下一个客户端的请求,比如我们负载均衡,去三号里边读数据了,但是由于三号通信故障,把一号的数据没同步过来,那它读到的数据不就不一样了吗?所以你一满足可用性,你发现又不一致了,所以你想要满足一致,那你就必须让三号机器不能访问,但它不能访问相当于我们就不可用了。
08:52
所以我们说的这个一致性和可用性只能二选一,而且大家注意,在我们分布式系统里边,永远我们都要满足分区容错,因为我们这个网络肯定会出现问题,所以呢,我们这个分区容错性,分区出错了,我们一定要想办法解决,但怎么想办法解决,那就二选一,那我们到底是要满足一致还是满足可用,如果满足可用,那他们能去访问,那相当于下一个人能访问三号机器,那他访问到的就是不一致的数据,那相当于你就容忍了这个业务能访问到不一致的数据,那么前边的人都是八,接接下来这个人访问却变成了七。
09:33
但如果我们想要满足一致,我们一定让他访问任何一个节点,那都是八,那这样的话,我们就不能让整个集群可用,如果我们让整个集群可用了,那发给一号二号的请求读出来是八,没问题,但是呢,发给三号的请求读出来呢是七。会不一致的,所以我们必须把所有的集群全部禁掉,你说你给一号机器保存了八,然后呢,只要三号机器没同步,我就给你不响应,说我这个八保存成功了,我就告诉你保存失败了,要不然我告诉你保存成功了,你还跑三号机器一拿,结果呢还拿出来了,所以我们现在就是说的一致可用,必须二选一,而P我们是必须要选择的,所以呢,我们这个C二选一,所以我们组最终我们的分布式系统里边,要么是一个CP系统,要么是一个AP系统,C系统做不到,因为你没办法保证你的网线不断,网络不中断,除非你就是单台机器,单台机器自己连自己机器的数据库,自己连自己的red,所有的数据库red都装在一台机器里边。
10:38
那你可以来考虑CA,所以这个C呢,其实不就是本地了,所以我们不可能有CA,只有CP和AP,这就是我们说的CP定理,同样的映射到我们的业务里边,我们分布式系统呢,都得满足这个定理,但是我们现在来考虑,如果我们来说AP好,说我们分区错误了,我们让它可用,读到的不一致,就不一致三个节点,你突然去读三号节点数据跟一二不一样,那就不一样吧,我们满足AP的没得说,关键如果我们想要满足CP,我们在分布式系统里边,我们想要保证它一致性,即使网络出错了,我们都能一致,那怎么一致呢?我们牺牲可用,牺牲可用是一个方面,第二方面,我们能不能通过什么算法能保证它们之间的一致呢?
11:22
所以一般呢,我们在分布式系统里边会有一些一致性算法,典型的代表,比如有raft算法,还有我们的pencil sources算法等等等等,那么就以这个RFT算法为例,我们来给大家看一下在我们分布式系统中如何实现一致性,这块呢有一个非常漂亮的动画演示们来给大家看一下,我们来深刻的理解一下我们分布式系统的一致性,比如我们来看一下RFT算法,他呢帮我们来理解我们这个分布式系统cons,这个就是一致性好,我们来运行一下我们这个动画,首先我们来说它说什么是我们分布式系统的一致性,我们跟他以一个例子来作为示范来开始,好。
12:07
那现在我们来说,我们现在呢,有一个单节点的系统,假设呢,就这一个节点,我们一台机器,我们现在呢就一台机器好,那现在呢,我们来看举一个例子,我们现在呢,就是这个节点,这个机器想要呢保存一个数据,好,那我们就给它保存一个数据,比如我们就叫X,它呢保存了一个数据,然后呢,我们有一个客户端,假设我们呢,它就是数据库,我们有一个服务连上它,给它保存数据,我们有一个客户端,它呢可以发送一个数据给我们的这个服务器,让他保存,那这就是我们非开发非常常见的,比如这就是满SQL,这就是我们的订单服务,我给他发一个circleq,让他保存一些数据,好,那么现在呢,我们就给他发一个八,我们让他保存八,我们现在呢,必须来统一,在我们这个单节点系统里边,很容易达成我们的这个一致性,也就是说我只要给我们的数据库发送insert,比如保存一个八数据库,能给我返回保存八成功了,那肯定。
13:07
这就成功了,所以这块的一致性呢是很好做的,因为就不需要一致,就它一个系统,好,那接下来,但是如果我们现在变成我们现在有多个节点的话,我们怎么让多个节点都能保存相同的数据,因为我们后来要做一个集群,你访问任何节点都行,那么就来看一下,那接下来我们说的这个问题,就是我们说的分布式一致性问题,好我们来看一下我们的分布日期一致性,我们说这个RFT,它呢是一个协议,它可以来实现我们这个分布式系统的这个一致性。走好,我们就站在一个上帝角度,我们来看一下他是怎么样工作的。现在呢,我们先来看我们现在呢,一个节点a node,它呢有三种,1OF3,有我们三种状态,这三种状态呢,我们先来记一下,第一种叫flower,就是我们的随从,能翻译过来呢,它叫随从,那还有我们的第二个状态叫can that,这就是我们说的候选者,那虚线框表示呢,我就是一个候选人,然后呢,还有第三个状态叫leader,如果是实线,那他就是一个领导,比如说一个任何一个节点都有三种状态,是随从,候选人还是领导,那接下来我们就来看我们现在呢,所有的节点,我们现在一号机器,二号机器,三号机器的满S,假如呢,我们现在启动。
14:32
我们呢,都是以一个随从状态启动的,所以呢,默认三个节点呢,都是随从状态走,然后呢,他说如果我们的这个随从,就是我们这个随从,他没有听到我们的这个领导者,相当于没有监听到领导者给他发的消息,那他呢就会变成一个候选人,也就是他觉得没有领导命令他了,那他就是候选人了,他准备当领导了,好假设呢,就是这个随从,他呢没有听到人命令他,那他现在变成领导,不应该变领导,他那先变成一个候选者,来看他怎么工作,首先我们这个候选者。
15:09
他呢,接下来会给我们所有的其他节点来发送一个投票,好那就是我们这样,他呢发一个投票出去,那发完投票以后呢,将来其他节点那就会回复他的这个投票,相当于他要让他们投他为领导,好,那现在呢,他们都投他为领导了,那他就变成领导,然后呢,我们这个节点呢,只要收到我们大多数节点的投票,那如果现在有三个节点。大多数节点,那就是包括他自己还有一个节点,只要两个节点呢,能同意他成为领导,那他呢就是领导,那接下来我们的这个过程叫一个leader election就是领导的选举过程,就是为了保证分布式系统的一致性,我们先来选一个领导,选一个领导以后,接下来怎么办走。接下来我们看all changes to the system,就是所有对于我们这个系统的改变,现在呢都得通过我们这个领导来变,所以你想要修改这两个节点的数据,你也得给领导发请求才能修改好。我们现在来看一下,现在假设我们有一个客户端,然后呢,他想要让我们这个分布式系统里边保存一个五,所以呢,他会给领导发送一个保存五的命令,假设呢,领导现在呢,记录了一下,我要保存五赛特五。
16:28
然后接下来。每一个这个改变的这个命令,他们呢,都会被添加成一个节点日志的方式,所以呢,如果我们这个客户端命令它保存物,我们领导呢,先会给它里边放一个日志叫赛特五,假设就叫赛特五,然后接下来我们这个日志当前呢是没提交状态,我们现在看如果是红颜色,那就是呢,Uncommitted没提交,所以呢,我们这个领导其实不会改变他这个节点的数据。比如说呢,你命令我保存五,我现在只要没提交别的人从我这儿读,那就不是五,那接下来应该怎么做呢?我们可以来看一下我们to commit,我们提交我们这个日志,我们的这个节点呢,现在我们有一个日志SET5了,它首先呢,它会复制我们这个日志去其他的随从节点,然后你命令他保存五了,他记录了一个日志,并且呢,给随从这些节点把这些日志呢也发出去了。
17:25
相当于随从节点也收到日志,叫赛特五,而且呢,只要随从节点把所有日志都收到了,给他们,随从节点里边也写了赛五以后,就会响应领导说,诶,我这个日志呢已经写好了,那领导呢,就会等待我们这个大多数的这个随从节点只要把这个日志都写好了,然后呢,我们发现领导这一块呢,只要收到大多数节点说日志写好了,他呢就提交了,他就SET5变成黑颜色,这个黑颜色呢,现在就提交了committed。所以我们这个领导节点的这个数据,现在呢,就是一个五,那接下来怎么办?我们这个领导呢,只要一变成五,我们这个领导就会通知其他随从节点,只要他自个儿能提交成功,有可能领导自己刚要提交,自己还炸了,所以呢,他只要自己提交成功了,他就告诉其他随从节点,我已经提交了,你们也可以提交了,那其他的随从节点呢,现在都提交成了五。
18:19
那至此我们客户端命令他保存一个五,他经过过来过去过来过去这么一个流程以后,五呢,才算保存成功,才会给我们这个客户端响应保存成功,只要我们客户端收到了保存成功。那一定是我们分布式系统里边这三个节点全都失误,好,这是我们说的这个过程,领导选举,那么现在的整个分布式系统就变成了一致性的了,所有的三个节点,现在呢,数据保存的都是五,所以我们把刚才的这个过程又叫做日志复制,因为我只要有啥变动,我都写一个日志,然后再来通知我的随从把日志记录一下,我提交了他们的也得都提交,所以我们把这个过程呢叫日志复制。现在我们有两个概念,一个是领导选举,在分布式系统里边我们得选一个领导,然后呢是日志复制,所有的改变通过领导,领导写一个日志,让随从也跟着写好,那我们再来接下来看其他的知识,来看一下我们的领导选举过程,那以上呢,只要按照我们的领导选举加上日志复制,我们就可以保证分布式系统的一致性,当然整个领导选举的过程是什么样的,我们也可以来了解一下,来看一下领导选举的过程。首先我们这个raft。
19:33
它呢有两个timeout超时时间,这个超时时间的设置呢,是来控制我们整个领导选举过程的,那这两个超时时间都是什么?我们来看一下,第一个超时时间叫选举超时election timeout,这个选举超时呢是一个什么东西们来看,他说这个选举超时是我们这个flower,我们这个随从想要变成一个候选者的中间的这一段时间,相当于我这个随从想要变候选者了,我有一段间隔时间,这个间隔时间是什么呢?一般是150毫秒到300毫秒,我们一般把这个称为节点的自选时间,就是150毫秒,在300毫秒之间,那么自己呢,自选,比如呢,我们150毫秒过后,还没有领导人给我发命令,我觉得我们领导了,那我就可以变成候选者了,我让其他人选我当领导。
20:25
它就是这个意思,好,所以相当于每一个节点先得有一个自选时间,那接下来我们来看,那现在我们三个节点呢,都自选,由于他们时间是随机的,好他先选到他的自选时间先结束,结束以后呢,他现在变成了候选人,我们看这个状态呢,是候选人,只要我们这个自选时间结束了,我们这个随从的这些节点就变成了我们候选人,我们刚才他的这个自选时间结束了,他变成了候选人。然后呢,他开始了一轮新的选举,所以我们看这terms terms就是轮,我们这是第一轮,然后呢,第一轮要开始来进行投票了,投票呢先来统计一个数量,一,他想让别人投他票,自己呢肯定得先投一票啊,所以这一块投票呢是一,然后接下来走,他先给自己投票,那么这块呢,变成了一,然后让别人再来投票,相当于给别人来发请求进行投票,And send out,把我们这个投票请求这个消息呢发给其他节点,好,我们走,现在呢,我们这个其他节点收到投票了,这个节点这个节点都收到了,这是我们的第一轮投票,所以呢,我们这个节点A节点也把票投给我们的B了,C节点把票也投给B了,也就说他这一块说,如果我们接收这个投票的这个节点,他当前呢还没有投票,他呢就可以给他投票了,如果假设还有另外一个节点跟你一样,同时给他发投票请求,他已经投过了,那他就不投你了。所以呢,每一个节点可能。
21:52
那只能投一票,那就是我们现在呢,大家都投了币,那现在呢,只要我们这个B节点大多数人投票成功,他就能成为领导,但大这一块呢,再来注意那这个node recess election time out,就是呢,我们这个只要一投票一成功以后,他们的这个节点会重置他们的选举超时时间,就是呢,我们看他这儿呢,有一个自选,只要呢,他把票投出去了,他就从零开始又自选,所以呢,只要他这儿有收到命令或投了票,他呢就会重新自选,所以我们现在看到呢,就是这个样子,AC呢都投票给B了,B呢现在就变成了领导,只要B变成领导,那接下来我们the leader,那们这个领导呢,接下来就开始发送这些追加日志,把这个日志呢发给这些随从们,这个领导呢,知道有这么多随从,然后接下来给他们来发日志,但是接下来再注意,那么这个消息的这个发送,它呢,也有一个这个超时时间,叫他beat come out,就是心跳。
22:52
时间相当于我每隔一段时间就要给他发一个消息,每隔一段时间就要发一个消息,相当于我们要维护一个心跳连接。所以我们现在看。
23:01
B呢,收到投票以后,在下一个心跳往出发的时候,就会把这些信息呢发给其他节点,其他节点一收到消息又自动重置,他们的选举时间就是我们的自选时间,所以我们接下来整个节点呢,跟其他节点就一直会维护这个心跳,但这个心跳呢,肯定不能超过300毫秒,一超300毫秒大家都自选成候选者了,所以心跳时间很短,比如十毫秒,五毫秒,或者我们100毫秒,我给你发一个心跳。那现在呢,这个心跳就只要这个节点系统建立好关系,他是领导,他是随从,他们之间呢,就不断的使用心跳来维护他们的关联,然后呢,他说我们这个领导选举,我们这一轮选举呢,一直会维持,维持到什么,一直到我们有一个随从节点stop,我们有一个这个随从节点呢,停止了接收心跳。并且成为了一个候选者,什么叫停止接受心跳,来看一下,假设呢,我们现在是这种情况情况,那现在呢,心跳维护的正好,然后呢,他停到掉了我们这个领导节点,像那么这个领导节点呢,干活干的正好呢,结果机器突然断电了,那怎么办走。
24:14
好领导节点没了,领导节点没了以后呢,这两个随从在他的自选时间,我们这个呢选的快,只要一选时间一到,他就变成了候选者,他要让别人投票,因为这个人呢,给他投不了票了,他自己一票加上他一票已经超过大多数节点了两票,那么我们A又变成了我们的新领导,以后所有的改变呢,又跟着这个新领导走,而且新领导的数据其实就是老领导之前的数据。所以呢,整个数据是一致的走,也就是说他需要呢,大多投票,只要成功以后呢,我们现在就变成了新领导。而且呢,每一轮只能选举出一个领导,这是肯定的。但现在大家来看,如果to move们现在如果有两个节点都变成了候选者,我们同时呢,都变成了候选者,我们这个投票呢,将会出现我们这个投票分离这个现象,来看一下这个投票分离是什么现象,来看一下我们的这个效果,现在我们来看大家呢,都在这儿自选,没有领导人命令了,现在肯定有两个节点同时选到时间好,现在大家注意观察A和C。
25:22
好,A和C呢,现在两个节点都悬到时间了。他们呢,是第四轮选举,第四轮选举,然后呢,看C呢,先投自己一票。A呢,也先投自己一票,然后呢,他们再给其他三个人发命令投票,相当于他们去来抢票了,那怎么抢呢?走,那给命令以后,接下来大家注意,那么这个B和D,由于这两个节点呢是随从,那B呢,他现在由于A的这个投票优先到达了B,所以呢,B现在投票给A了,那C的投票想要交给BB呢,就不投了,他已经投给A了,然后呢,D这个节点由于C的这个。
26:04
投票请求优先到达了D,所以呢D投给C了,所以呢,我们A给他发的这个请求,他呢相当于就拒收了,相当于我们每一次呢,这个投票请求只能到达一个我们这个随从节点。只要别人没没进来,只要我一进来投票了,那别人的投票请求那就进不来,好,那现在我们来看,现在他们都投票了以后,那假设呢,票数统计还一样,A和C节点现在假设都投到了两票,那接下来怎么办呢?我们来看,那都投到了两票,然后呢,又重新来一轮自选。好,我们先来等待,现在这一轮自旋呢,我们发现C先选到了。然后呢,我们再来看前面呢,我们有几个过程过得非常快,跳过了。就是呢,我们这个选举呢,已经变到六轮了,刚才我们选的那一块大家都变成候选者都想要投票了,结果最终呢,我们这个C在第论六轮投票的时候,他呢抢到了大多数节点的票,那现在呢,我们这个C呢,就变成领导了,那刚才那个过程呢,就是我们说的领导选举的过程,主要呢,要不断的让随从节点给我们这个候选人投票,而且呢,只能投一个候选人,我们就不断的城市第一次投票失败了。
27:23
两个呢,都失败了,那么就重新投,失败了再重新投,直到我们这个投票成功,选到一个新的领导人,那么以后呢,就跟着这个领导人来同步他的状态,这是我们刚才说的领导选举,我们再来看一下我们说的日志复制,日志复制的过程呢,应该是这样子的,我们假设呢,我们这个B节点。他呢,现在是领导,A和C呢,都是随从,比方说我们这个领导人呢,他必须把我们所有的这个改变,我们都得复制给我们这个节点系统的其他节点。那怎么复制呢?我们就是使用这个日志的方式,而且这个日志呢,是在每一个心跳的时候发出去的,假设呢,我们这改变了一个数据,我们来看一下我们整个过程,好,我们现在呢,这有一个客户端,我们让领导呢变成一个五,那这个五的日志写到这儿以后呢。
28:12
不是说领导收到请求立马发出去,而是在他下一个心跳好,下一个心跳该发请求了,那就把这下一个心跳我们来发给其他所有的节点,那所有的节点呢,带上我们这个日志,所有的节点现在都同步了,有一个赛特五日志,而且所有的节点都给他回复了,不是所有节点,是大多数节点只要都给他回复了。那么这个呢,领导就觉得大多数人都跟他,那我们的就可以提交了,赛五那领导的这块一提交在下一个心跳时间,只要领导这个一提交,他们就会响应给客户端,我已经成了在下一个心跳时间。告诉我们其他的系统你再去给我提交一下,所以呢,其他的系统呢,现在就提交过来了,假设呢,我们现在又要让他保存二,那还是一样,其他系统一同步,诶成功,那就这样,所以呢,我们现在呢,整个系统就是我们这么一个流程。
29:08
我们是通过在心跳时间的时候,给他发送日志的时候,我们让其他的节点同步我们的这个改变日志。好,这我说的日志复制。而且呢,我们说这个raft,它可以保持我们这个一致性。在面临我们这个网络分区的时候,就是如果我们先发生了这个网络故障,比如我们这两个节点呢,突然网线不能访问到了,即使面对这些网络分区,我们也可以保证一致,怎么保证一致,大家来看一下走,假设我们看现在呢,我们来分割AB和CDE,那就是AB这两个节点,假设呢,我们把它放到了一个机房,CDE呢,这个在一个机房,本来两个机房之间有连线,结果这个线呢,突然断了,那接下来怎么办呢?来看一下走。
30:03
现在出现了分区,一出现分区以后呢,就各自选领导了,那我们上边呢,这一块呢也得选领导,下边呢,原来B是领导还是领导,上边呢,自己给他们重新投了一个领导,而且呢,他们这个领导还候选人挺多的,我们让他慢慢投。好,那现在呢,看到我们这个E节点赚到了,那现在呢,好要投。这两个呢,又马上都要转到他优先转到好投,那现在呢,我们投给他,那现在呢,我们这个E节点,就是我们上边这个区域的领导,所有的数据呢,相当于都要通过它来进行改变,然后接下来我们来看一个效果,如果我们现在有两个客户端都想要操作我们这个集群,那下来怎么操作我们第一个客户端假设呢,他命令我们这个B节点去来改成三。它的这个一个保存三请求发给B节点,B节点呢,让A节点同步保存三,然后呢,接下来回复A节点给他回复,由于呢,我们这个B节点,它之前呢,总共有12345个节点。
31:08
所以呢,他想要提交他的这个保存三请求,那必须大多数节点同意,而我们现在呢,只有他两个节点算上他自己算上这个人才两个节点,所以呢,他做的任何事情都不能收到大多数人的响应,所以这样的话呢,我们这个B节点的这个三就是一直没有提交的,所以你给他发命令保存啥,他都告诉你没有保存成功,没有提交,那接下来我们来看一下,如果我们给这个给我们E节点发送保存八,保存八以后呢,我们一节点让其他人同步好都保存了八,保存了八以后,那接下来怎么办?但是大家这一块注意,B节点呢,是在第一轮选举产生的领导,然后呢,我们这个E节点是人家上边的这个分区经过了好几轮竞争以后来产生的新领导,经过了四轮竞争,那接下来假设我们这个网络通了,我们分区又恢复了,恢复了怎么办?来看一下我们的效果,要说我们这一块呢,将会成功,因为它能收到大多数节点,那么一节点呢,它能保存我们这个八,因为带上一节点,带上这两个随从,它呢有三个节点,所以呢,它能保存来八的数据,那保存来八的数据以后呢,我们来看怎么办?假设我们现在恢复了我们这个网络分区,走那一恢复分区以后呢,我现在有两个领导,然后呢,我们的B领导,由于他是老领导,他呢要看更高中选举的,所以呢我们高中选举的新领导是E,所以呢B他就退位了。
32:38
他呢,就认为他的领导呢,是一是人家高中选举来的现代社会的领导好,那接下来怎么办呢?走接下来我们的AB节点,AB节点这两个人一看,这A呢,他之前跟的这个领导是老领导,这个新中国这儿成立了,这一块大清都亡了,所以他这一块的数据怎么办呢?他肯定就不提交,所以呢,我们B跟A他两个节点的所有数据,他全部呢回滚,相当于他没提交的这些日志,不应该是所有是没提交的这些。
33:09
我们在一发现分区错误以后,所有操作来的数据,没提交的数据,他们都要回滚,回滚了以后呢,又来再来匹配我们新领导的日志,相当于把新领导的赛特八拿过来,拿过来呢再一同步,同步以后呢,我们整个系统都变成了S8。所以呢,这就是我们说的,他能容忍我们这个分区错误,整个容忍过程呢,就是这样子的,那现在呢,我们这个状况就是我们所有的这个日志,现在都是一个一致性状态。我们整个节点集群呢,现在都是一致的,所以我们这个raft算法几个核心,第一个是领导选举,第二个是日志复制,通过他们来保证我们整个集群的一致性,即使有分区错误,我们也能产生一致性。当然领导选举以及发送这些日志牵扯到两个时间,一个自选时间,决定我们要不要变成候选人当领导,另外一个是心跳时间,我们在心跳时间把日志发出去,所以呢,这是我们说的raft算法,那这一块呢,我们就给大家普及一下我们这个raftt,我们来深刻的再来理解一下分布式系统里边的一致性问题,大家有一个大致的理解,当然详细的东西呢,还可以看我们这个raft相关的这个网站里边的内容,包括raftt相关的这一块算法,它呢也有一个比较好的动画演示,大家也可以来参照一下,咱们下面这一块,我们看一下,它这一块呢,也有一个动画,我们可以让它高倍速的运行,也可以低倍速的运行。
34:42
我们可以看一下我们整个这一块过程是什么样的,比如我们让二号节点保存一个数据,你可以点进去发一个request,让它保存一个数据,我们能看到S3呢,现在想要保存二,他们整个过程是什么样的,我们可以在这把暂停点一下,让他开始,他呢给其他人都复制来日志,然后呢他一提交。
35:02
那下一个心跳走再过去其他人呢都提交,那我们整个这个过程呢,都能看到,包括我们这个主节点如果断了怎么办。比如我们给他STOP1停,一停以后呢,我们重新来,那这些人呢,接下来给主节点回复,结果呢,主节点没有给他回复,相当于他们的领导给挂了,那接下来怎么办呢?那我们来看一下这些人呢,只要到了他的自选时间,那这个人先到,那他呢,就会发送我们的候选请求,他最终成为我们的领导,然后呢,要保存什么数据,比如我们给他保存一个数据三,那接下来想要保存的数据呢?怎样的一个同步状态我们都能看到,但是只有我们这个S3节点我们没有同步,因为这个节点呢,现在已经挂了,如果我们把它重新启动起来。那么现在呢,就能看到我们整个的同步状况,我现在把它restart重启起来,那重启起来以后呢,来看一下节节点效果,那S2 S2呢,给其他人都能发了,给他呢也能发了,那把它弄通了,通了以后呢,他就得把S2里边的所有东西复制过来。
36:05
那至此呢,这也是我们整个raft算法的一个图示流程,参照哪个呢?都比较看起来比较人性化一点,那我们比帮助我们理解raft,通过raft我们更应该深刻的理解什么叫一致性,特别是分布式系统里边的一致性,一旦网络分区一出现错误以后,他又怎么样去来恢复这个一致性,那其实我们这个分布式的事物就是想要这样,那ABC3个节点系统订单库存以及我们的用户系统,他们倒不是说只保存一个八这个数据这么简单,他们想要。达成一个一致状态,三个都成功了,那就算成功,有一个失败了都得失败,而且呢,就算不失败,这两个成功了,这个人最终只要启动起来了,还得跟他保持一致的状态。要么成功,要么失败,所以呢,这是我们分布式事务要做的事情,保证我们分布式系统里边我们这些数据的一致性。
我来说两句