00:00
呃,哈喽,大家好,今天呢是我第一次以录视频的形式来给大家分享一些和技术相关的一些内容啊。呃,今天分享的主题呢,就是分布式一致性算法,然后对于这个,对于这个主题呢,呃,我是准备录制一整个系列去分别描述,呃对于这个系列呢,我大概罗列了这么一些内容啊,比如说有呃二阶段提交,三阶段提交,还有帕s raft zb,还有CP和base斯理论,这个东西之所以放在相对来说比较靠后来讲,是我有一定的,我自己有一定的想法,如果在第六讲还能呃见到大家的话,那呃,那到时候再给大家一起再给大家来分享。呃还有说1PARTLES,还有fast partles都是对于parts的一些变种,呃相对来讲啊,这一个系列的内容呢,还是比较多的。
01:00
也比较比较完整,所以说呃。希望大家持续关注吧,然后对于这些内容呢,我其实已经在我的公众号里面都有做过一些提前的更新了,呃,如果想大家想提前了解一些之后的话,可以关注我的一个公众号,公众号呢就叫做一个兵法笔记,大家可以搜一下啊,然后还有我的个人博客里面也要做个提前的更新,然后博客里面可能更新的快一点。呃。嗯,然后讲一下我后面视频的一个风格吧,呃,我后面录的一个视频呢,不会占用带大家太多的一个时间,就比方说嗯,大概大概一个五六分钟吧,不会说录个录上个一个小时啊,两个小时这样子,我相信大家也没那么多时间去听,呃,好了,我我们今天的一个内容就是二阶段提交,那么二阶段提交呢,就分为这三块内容啊,有这个一致性算法的一个背景,还有R阶段提交协议,它本身的一个原理和它现存的一些问题啊。
02:17
嗯,好了,我们接下来看第一个问题,那第一个问题呢,嗯,分布式一致性的算法的一个背景啊,就比方说我们现在,呃,我们现在在开发过程中啊,多多少少啊都有了解过分布式,分布式的一些知识,那么在分布式的场呃环境下呀,我们就会经常聊到一个分布式事务的问题,怎么去解决掉它,那么我看我接下来,呃,我现在举的这个例子,就比方说我现在我有一个客户端去调用我的一个service a服务,然后我service a服务呢,去调用service b服,然后service的话还要调用service c服务,然后service b服务,Service c服务,他们分别都操作自己的数据库。
03:07
这面都抄了自己的数据库,呃,我们知道在我们的开发过程中,在单个节点下,如果要保证一个事物的话,相对来说还是比较简单的,我们spring spring呢,就有给我们提供一些很多的方式,比如说给我们提供了一些transaction抽解啊,我们都可以拿来简简单的去实现,也很好用。那么在对于分布式场景下呢,我们期望的是啊,就是说service a啊,Service a和service b,还有service a,它也能够保证一个事物,呃,就是说。对于客户端的这个请求来讲,客户端的这个请求来讲,Service a和service b,还有service c这三个,这三个。节点所操作的数据库的一些内容,我们期望呢,它是呃原子性的,也就是说要么是呃一起提交成功,要么是同时失败,要么是同时成功,不会说出现这个呃,Service b提交成功了,然后service c没有提交成功,这是这这是我们分布式失误,就是要解决的一个问题,呃,然后还有一个场景呢,就是说一个副本容错的一个问题,呃,比方说我现在我一个客户端啊,在操作一个数据库的时候啊,因为它是一个master的节点,然后呢,我们希望这个master的节点,它在宕机的时候,它的数据还能够保证一个准确性,也就是说我们会对这个master的存呃。
04:48
提供多个副本支持,也就是说在每个副本上都保存了master的相同的内容,然后当master宕机之后,然后我们的副本能够能够。
05:04
还有还拥有一个完整的数据,就是说这样一个场景,呃,那么我们接下来来看一下RPC,它是一个什么简单的一个描述,然后二阶段提交呢?我们主要强调的是,呃,它是一个强力执性去中心化的原子提交协议,那么怎么去理解这一句话呢?呃,强力执信啊,来,我们回到上一个案例来讲,强烈执信是指就是说这个客户端对这个master进行了一个写操作之后,这个master对呃,Slave都写入成功了。嗯,接下来我们的,呃,客户端不管是访问哪一个level。都能获取到一个最新的数据。跟获取到跟master一致的一个数据,这就是一个强一致性的一个体现。
06:06
那么去中心化呢?去中心化是因为呃,二阶段提交,它提供了一个两个角色,一个是协调者的参与者,那么对于这两个。角色所干的事情呢,协调者就是协调整个事物的提交和回滚,然后参与者呢,就相当于说上面的slave节点,呃,这里的service b服务和service c服务,这这两个服务就相当于一个,呃,参与者啊,这里service a呢,它就可以充当一个协调者的一个,这样子理解。所以说呃,当我们的一个协调者,他宕机之后,整个就是说整个集群也处于一个不可用的一个状态,所以说我们说它是一个去中心化的一个协议,而是一个中性化的协议,然后原子原子性呢,原子性就是相当于嗯,在这个在这个案例来讲啊,就master和两个slave slave他们要么是同时修改,同时修改成功,要么是同时修改失败,这就是我们原则性的一个体现。
07:26
然后二阶段提交协议呢,呃,顾名思义,它是分为两个阶段,第一阶段就是准备阶段,第二阶段呢,就是提交阶段,那么我们接下来一个一个来看啊,那么对于二阶段第一第一阶段第一阶段也就是说他的准备阶段。啊,现在我有一个客户端。呃,像我们的协调者发起的一个,呃事务事务性,呃事务操作,然后这个协调者呢,他要去更新两个参与者的一个内容。
08:05
嗯,那这个时候。我们协调者就会干一件事情,就是先向各个参与者发送一个prop请求,然后这个prop请求呢,是告诉参与者,嗯,现在我要进行这个事务操作,你那边能不能提交成功啊,然后呢,当这个参与者啊,收到了这个prop请求的时候,嗯,这个时候他会根据自身的一个业务场景啊,会对这个呃,Prop请求,当然这个prop请求会包含这个事物具体的一些操作内容,然后呢,它会呃,我们参与者就能够知道这个事务操作他本身能够能不能够提交成功,如果能够提交成功的话,那么他就呃进入当前的一个日志,事务日志,比如说呃,Radio啊,Undo日志,然后记录成功之后,然后给协调者返回成功或者失败,这yes or no。
09:08
的意思呢,就是说呃,告诉协调者啊,这个事物我这边可以提交,提交了可以提交,然后通知你,然后no呢,就是说告诉协调者这个事物我这边还提交不了,你就不要提交了。然后这就是RPC的第一个阶段,也就是说准备阶段的一个过程。那么。这样做有什么意义呢?就是说协调者他。去先去询问询问每个参与者能不能提交,然后如果能提交的话,他再进行第二个阶段啊,第二阶段也就是说提交阶段,那么提交阶段呢,它其实是分为两部分啊,一个是真正的提交阶段,因为我们上面也可以看到嘛,在第一阶段的时候,呃,参与者可以给协调者返回no的这个A响应就是A啊。
10:07
可以返回noe这个AK响应,那么在协调者收到呃有返回node这个AK的时候,就会处理呃另一个步骤,也就是说一个回滚的一个步骤,所以说我们的第二阶段分为两个部分,一个是提交协议,还有一个是回滚。啊,我们现在看提交协议,呃,当我们协调者收到所有的参与者都能提交这个事物的时候啊,那么他就会发起第二阶段的提交,然后我们的协调者呢,向所有的参与者发发送一个global com的一个协议,啊,像所有的参与者都发送这个global com的一个消息,然后参与者在收到这个消息的时候啊,他就会将我们之前记录的呃,Ondo日和radio日志进行一个处理,然后提交本地的一个事务,也就是说第六步提交本地的一个事务,然后他处理成功之后呢,然后接着会给协调者返回一个A。
11:15
然后协调者收到所有的A之后呢,就给我们的客户端返回成功。然后刚刚说的二阶段会有一个异常的一个场景,也就是说在第一阶段的时候,协调者他收到了呃,No的一个A响应,那么他就会发起一个呃,事物回滚的一个消息,也就是说他在第二阶段会给所有的参与者广播global,呃的这个消息,然后所有的参与者说到这个消息之后啊,他就会把第一阶段所记录的ondo redo值进行一个事物的回滚,就是说他本身。
12:00
每个参与者本地的事物的回滚,然后回滚之后呢,继续给协调者反馈一个ACK消息,然后ACK收收到所有的AK消息之后,协调者收到所有的AC消息之后,然后就给客户端反馈失败,然后呢,这整个过程呢,就是RPC的一个二阶段提交的一个描述。那么二阶段提交呢,他呃存在的一些问题,我们也可以很明确的看到啊,就是比方说嗯,等一下啊。比方说我们在第一阶段的时候啊,嗯。我们的协调者要收到所有的参与者的A,就是说他的yes or no的消息之后,他才会发起第二阶段。
13:03
而我们的参与者呢,也会一直等待我们协调者呃发送第二阶段global或者是global的这个消息,所以说会存在一个同步阻塞的一个问题啊,同步阻塞体现在什么地方呢?就是说呃,第一个部分,第一部分是我们协调者必须要等待所有的参与者给他的一个A消息之后,他才会发起第二阶段,第二个阻塞的地方呢,是在于呃,我们的参与者。要等待协调者向他们发送global和global的消息之后,他才会进行第二阶段操作。那么这个这两个阻塞听起来是理所当然,但是它会带来一系列的问题啊,就比带来什么问题呢?就比方说,呃,我们的协调者。
14:02
在操作第一阶段,第一阶段发送消息给所有参与者之后,说参与者都记录了事务日志结果之后,然后这个时候协调者宕机了。也就是说没人去发起第二阶段了,那么我们的所有的参与者,他他都堵塞在第一阶段,阻塞在第一阶段,因为他需要等待协调者的那个第二阶段的消息嘛,就是global com global或者是global commit的这个消息,但是现在没有协调者给他们发了,所以他们一直阻塞在哪里啊,这就是一个二阶段提交协议存在一个同步阻塞的一个问题,然后他还会存在一个数据不一致的一个问题,那么数据不一致的问题呢,是指那个,呃。比方说啊,呃,我们现在。嗯,我们协调者操作完,就是发起第一阶段操作之后啊。
15:06
然后所有的参与者都给协调者返回yes,子响应了,返回yes的A响应了,那么这个时候协调者开始开启第二阶段global com协议,那么这个时候。协调者把一部分的一部分的那个参,像参与者广播global com消息的时候,一部分已经广播完成了,然后另一部分呢,还没有广播,协调者这个时候宕机了,或者说因为网络的一些请求,呃,一部分的参与者他没有收到第二阶段的global,呃commit的一个消息,也就是说这个时候就会造成一个问题呢,就是说有部分收到了第二阶段的消息的参与者,那么他就处理成功了,然后没有收到第二阶段消息的参与者,他就没有处理成功,那就这就是一个不一致,不一致的一个问题,然后存会存在一些单点的问题,还有老练,单点问题和老练呢是指。
16:12
可以看,可以回顾我们刚刚讲的二阶段的整个过程啊,它是其实是完全依赖这个协调者的,也就是说协调者宕机了。那么我们整个集群就不可用了,这就是一个单点的问题,然后老列呢,老列是指就是说当我们的这个集群比较大的时候啊,容易出现一个网络分区的一个情况,网络分区呢,也就是说会出现多个协调者。存在的情况,这就是说有多个协作者去处理请求,那这个时候肯定是处理的数据肯定是不对的,对吧?那么这就是一个老列的一个情况,然后太过保守,太过保守呢是指,嗯,我们可以看到啊,就是二阶段,二阶段提交协议,他在描述整个协议的时候呢,他需要等待所有的参与者操作成功之后,他才进行,呃,接下来的操作,接下来第二阶段的操作,或者后面操作,那其实呢,这其实是太过于保守了,呃,在一些情况下,它其实是可以做一些优化的。
17:26
嗯,这一优化呢,我们后面在讲到一些帕算法的时候,大家可以了解得到,那么这就是今天的所有的内容,二阶段提交协议呢,他回顾一下吧,回顾一下他是一个强硬之性呢,今天没有写那个总结的那一张PPT啊,我们简单回顾一下那二阶段他那个。简单描述就是一个强一致性的中心化的一个原则,提交协议,它解决的问题呢,就是分布式事务,还有那个呃,多副本的一个场景,我们都可以去用到二阶段提交协议,然后。
18:12
二阶段呢,它分为两个阶段,一个是准备阶段,一个提交阶段。准备阶段呢则是指就是说询问每个参与者,每个事物的参与者,他能不能提交当前的事物,然后提交阶,提交阶段呢,就是说协调者告诉每个参与者是否要真正去提交这个当前的事物。然后还有他二阶段提交了,他分为两个角色,一个是参与者,一个是协调者,那么这就是二阶段提交协议的一个概述,那我这里再加一个记录一下。记录一下他的一个场景,等一下我们场景,场景就是。
19:03
呃,然后它存在的问题呢,就是存在四个问题,一个是同步阻塞,还有是数据不一致的问题,然后刚刚都已经,呃。呃,解说过了,还有单点以及老列的问题,还有太过保守,那么要解决这四个存在的问题啊,我们下一节就是讲到三阶段提交,三阶段提交呢,解决了这四个问题里面的部部分问题啊,就比如说同步阻塞,呃,同步阻塞的问题,然后对于数据不一致呢,解决了一部分,然后还有一部分呢,也他不能保证完全的。一一致,然后单点问题和老练呢,还有太过保守的这个三阶段提交没有解决掉。嗯,好的,那今天我们的内容就到这里了啊,好,谢谢谢谢。
我来说两句