2PC,Raft和Paxos笔记

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shujiezhang/article/details/78066874

1. 用婚礼过程模拟2PC

  •     牧师(协调者):新郎,你愿意?
  •     未婚男(参与者A):YES, I DO.
  •     牧师(协调者):新娘,你愿意?
  •     未婚女(参与者B):YES, I DO.

  •     牧师(协调者):新郎,入洞房?
  •     未婚男(参与者A):OK
  •     牧师(协调者):新娘,入洞房?
  •     未婚女(参与者B):OK
  •     牧师(协调者):婚礼结束

             镜头切换到第二天早清晨。。。。。。。

2. 2PC的问题

2PC需要在每次事务提交时,就保证主机(协调者)和参与者一定处于一致性的状态,如果其中有一个参与者出现了故障或者网络问题,不能及时的回应主机(协调者),那么这次事务就宣告失败或者出现阻塞。也就是说对于2PC而言,事务的“原子性”体现在主机(协调者)和所有的参与者上,主机(协调者)和所有的参与者都要保证各自的事务是一个原子操作,从而保证了整个分布式的事务是一个原子操作。(例:就好像新郎和新娘必须全部同意入洞房才能成功,假设到了入洞房阶段,新郎猝死(参与者故障)或者新娘走错了房间(网络异常),结婚都不可能成功。)

如果参与者(假设在第二阶段)出现了网络问题,协调者可能有两个方案可选:

  • 方案一是不断持续的继续对未成功的参与者尝试再次提交,这时候就可能把整个分布式事务阻塞在这里,而整个分布式事务就无法提交了。
  • 方案二是尝试回滚那些提交成功的事务,这样在那些提交成功的参与者(单机)上,就违背了事务的“持久性”。

虽然上述两个方案有都有各自的问题,但只要协调者还“存活”,我们还是可以想办法保证这个事务的原子性。但是,假如这时候协调者出现故障,那么问题就来了,这种状态下新的协调者对其他的参与者的情况不了解,参与者对协调者的情况也不了解,这时候的这个事务的状态就是“未决”状态。

换个角度来看,上面的两个方案实际上是在2PC上增加了一个新的“阶段”:1)或者增加一个“不停尝试的阶段”,2)或者增加一个“回滚的阶段”。协调者既可以选择方案一,也可以选择方案二。当机器(非人)面临这种情况的时候,就需要外部给他设定一些规则,通过这些规则来告诉协调者这个中间状态的“转移函数”是什么,3PC的出现主要就是要解决这种未决的状态。

3. 3PC能解决问题吗

  上述的问题是在“提交(commit)阶段”出现了一种“未决”的状态,这种状态既不能保证所有的参与者事务都是提交的,也不能保证所有参与者事务都是回滚的。3PC2PC的“提交(commit)阶段”又分成了两个步骤,分别是“precommit阶段”和新的“commit阶段”。

  • 如果precommit阶段出现了异常,或者超时,在这个阶段事务默认是回滚的。
  • 如果进入到了第三个阶段——“commit阶段”,那么预示着各个参与者的事务是“可提交的”的状态。这种“可提交”状态,就是说事务现在已经万事俱备,只欠东风,即使在出现了异常,那么也可以通过超时机制,让各个参与者自己提交事务。也就是说,在第三个阶段,如果超时,事务默认从“可提交”状态转移到“提交”状态。

  这样,在2PC的基础上增加一个新的阶段,实际上是增加了一个新的状态,并且给这个状态增加了一个隐含的转移函数,也就是定义了一个隐含的规则,这个规则是在未决状态(非确定状态)向确定状态转移的函数。

4. 2PC需要两个阶段

  对比RAFT协议,我们发现RAFT协议在选主完成之后,会进入日志复制的阶段,而日志复制的阶段看上去是一阶段的,LEADER(对应2PC的协调者)把日志发送给FLLOWER(对应2PC的参与者),FLLOWER接收日志并按序“恢复日志”,保证各个主机的一致性。

  两阶段提交在开始的时候就已经指定了主机作为协调者,和RAFT很类似,协调者对应着RAFT协议中的LEADER,那么2PC中的第一阶段是不是可以省略?

既然2PC的发明者没有省去一个阶段,那么看上去RAFT协议和2PC还是不太一样:2PC的第一阶段主要的作用是要求参与者锁住资源,执行事务,而RAFT则没有这样的要求。或者从协议本身来看:

  • 2PC更关注的是事务的原子性。也就是说2PC是基于事务的,在事务执行之初通过第一阶段加锁,在事务执行结束通过第二阶段提交,2PC的一致性仍然是事务上的一致性,是因为2PC服务于一个分布式事务,这个分布式事务提交之后,数据自然就会保持一致。
  • RAFT更关注的是数据的一致性。RAFT中的日志传输阶段实际上是没有事务的概念的,这种数据的一致性是通过“日志的偏序关系”来保持的。

通过上面的分析,拿RAFT和2PC来进行比较,好像是不太合适的,或者说这两个协议产生的最初动机是不同的,虽然他们好像经常能达到所谓“数据一致性”的目标。当然上面说的不一定正确,只是基于个人的理解。    

5. PaxosRAFT都有第一阶段

            Raft的第一个阶段应该就是选主的阶段,在这个阶段,raft确定了一台主机作为当前的leader,另外给这个leader确定了一个termterm作为这个leader的任期。一旦leader当选,那么这个term就是这个leader任期范围内所特有的,如果要更换leaderterm必须也要递增。总之,raft选主确定了两个要素:LeaderTerm

  (以basic Paxos为例,)Paxos看上去是一个无主的协议,但实际上在paxos的第一个阶段,就是一个leader抢夺战,每个主机在第一阶段都会有一个提案编号,这个提案编号越大,则优先级越高。编号最高的主机获得了主的地位,一旦有新的更高编号出现,则“主”的地位发生变更,每个主机在“宣示”自己的编号失败后,都会递增自己的提案编号,以争夺“主”的地位,每个“主”的任期就是自己的提案编号(对应raft的term)。这么看来,Paxos和RAFT的第一个阶段有一定的相似性。

  不同的是,Paxos一旦达成了“多数派”的值,在第一个阶段还会把这个值确定。简言之,Paxos第一阶段要获得主动权,另外还需要把数据确定,这样才能展开第二个阶段。

  而raft的第一阶段(选主)则不涉及到数据的问题,raft的第一个阶段直选主,因为leader一旦确定,那么数据也就随之确定了,因为raft的数据是单向的从leaderfollower流动的。

6. RAFT的候选人角色

  个人感觉候选人角色不是必须的,至少从状态转换图来看,状态是可切换的(图是从网上扒的):

 

  切换一下:

          实际上,增加了candidate角色之后,会更符合现实的实际情况,从上面的图可以看出,合并了FollowerCandidate之后,这个角色上的状态切换变的更复杂了,实际上工作量也没有减少。当然上面说的不一定正确,只是基于个人的理解。

7. 给多数派做个说明

          RaftPaxos一样,基于多数派的原则,理论基础应该是鸽巢原理(也叫抽屉原理)。

  对于Paxos而言,如果某个值已经被n/2+1个主机接收,那么,其他主机使用更高的编号发起提案的时候,收到的返回信息里一定包含这个确定的值(这个确定的值就是“提案编号最大的那个值作为初值”),一段白话描述(很白)

  • 如果第一阶段的“返回信息”里没有值,那么自己初始化任意值。
  • 如果第一阶段的“返回信息”里有一个或多个值,那么选择提案编号最大的那个值作为初值

举个例子,A,B,C三个主机来确定某个值。

1) 首先A主机发送1号提案给BC

2) B收到1号提案,表示可以接受,并记录下已经接受过1号提案。

3) A在第一阶段已经获得了多数派,但是B并没有给他返回值,因此A可以任意设定初值(如果第一阶段的“返回信息”里没有值,那么自己初始化任意值。)。

4) A进入1号提案的第二阶段,并指定自己的初值为x

5) B再次收到该提案,发现自己已经接受过1号提案,1>= 1,因此接受x值。

6) A收到B的确认消息,到这里——AB都已经接受了x值。

这里就可以发现,AB是多数派,已经确定了x值,假如这时C发起一个3号提案,那么:

 7) AB收到C3号提案第一阶段,会把自己当前接受的值回送给C,并且告诉C是这个值x1号提案的接收值。

8) C如果想自己的第一阶段成功,那么必须满足多数派的原则,C的多数派中必然要包含A或者B的其中一个。那么就必然会获得这个已经确定的初值x。 (如果第一阶段的“返回信息”里有一个或多个值,那么选择提案编号最大的那个值作为初值。



猜你喜欢

转载自blog.csdn.net/shujiezhang/article/details/78066874
2PC
今日推荐