分布式一致性算法2PC,3PC和经典的paxos

 

 

  本篇文章讲的是分布式一致性算法的理解,主要是理解和整合2PC,3PC和paxos算法的:html

首先咱们说说分布式一致性的两个概念,一个是分布式设置不一样的业务逻辑,来达到分布式的一致性,好比分布式系统收帐服务系统和付帐服务系统,收帐表和付帐表是不一样的数据库,人是要付出了钱,机器收了钱,保证钱数是对的,才能保证分布式的一致性,这个应该叫分布式业务逻辑一致性,还有一种就是都是同样的数据库,只是主库和备份的关系,这个叫分布式数据一致性,掺杂业务逻辑。算法

先说2PC和3PC数据库

为了解决分布式一致性问题,产生了很多经典的分布式一致性算法,本文将介绍其中的2PC和3PC。2PC即Two-Phase Commit,译为二阶段提交协议。3PC即Three-Phase Commit,译为三阶段提交协议。网络

分布式系统和分布式一致性问题

 
  分布式系统,即运行在多台不一样的网络计算机上的软硬件系统,而且仅经过消息传递来进行通讯和协调。
  分布式一致性问题,即相互独立的节点之间如何就一项决议达成一致的问题。
 分布式

2PC

 
  2PC,二阶段提交协议,即将事务的提交过程分为两个阶段来进行处理:准备阶段和提交阶段。事务的发起者称协调者,事务的执行者称参与者。
 
  阶段1:准备阶段
  一、协调者向全部参与者发送事务内容,询问是否能够提交事务,并等待全部参与者答复。
  二、各参与者执行事务操做,将Undo和Redo信息记入事务日志中(但不提交事务)。
  三、如参与者执行成功,给协调者反馈YES,便可以提交;如执行失败,给协调者反馈NO,即不可提交。
 
  阶段2:提交阶段
 
  此阶段分两种状况:全部参与者均反馈YES、或任何一个参与者反馈NO。
  全部参与者均反馈YES时,即提交事务。
  任何一个参与者反馈NO时,即中断事务。
 
  提交事务:(全部参与者均反馈YES)
  一、协调者向全部参与者发出正式提交事务的请求(即Commit请求)。
  二、参与者执行Commit请求,并释放整个事务期间占用的资源。
  三、各参与者向协调者反馈Ack完成的消息。
  四、协调者收到全部参与者反馈的Ack消息后,即完成事务提交。
 
  附以下示意图:
 
分布式一致性算法2PC和3PC
 
  中断事务:(任何一个参与者反馈NO)
  一、协调者向全部参与者发出回滚请求(即Rollback请求)。
  二、参与者使用阶段1中的Undo信息执行回滚操做,并释放整个事务期间占用的资源。
  三、各参与者向协调者反馈Ack完成的消息。
  四、协调者收到全部参与者反馈的Ack消息后,即完成事务中断。
 
  附以下示意图:
 
分布式一致性算法2PC和3PC
 spa

2PC的缺陷

 
  一、同步阻塞:最大的问题即同步阻塞,即:全部参与事务的逻辑均处于阻塞状态。
  二、单点:协调者存在单点问题,若是协调者出现故障,参与者将一直处于锁定状态。
  三、脑裂:在阶段2中,若是只有部分参与者接收并执行了Commit请求,会致使节点数据不一致。
 
  因为2PC存在如上同步阻塞、单点、脑裂问题,所以又出现了2PC的改进方案,即3PC。
 .net

3PC

 
  3PC,三阶段提交协议,是2PC的改进版本,即将事务的提交过程分为CanCommit、PreCommit、do Commit三个阶段来进行处理。
 
  阶段1:CanCommit
  一、协调者向全部参与者发出包含事务内容的CanCommit请求,询问是否能够提交事务,并等待全部参与者答复。
  二、参与者收到CanCommit请求后,若是认为能够执行事务操做,则反馈YES并进入预备状态,不然反馈NO。
 
  阶段2:PreCommit
 
  此阶段分两种状况:
  一、全部参与者均反馈YES,即执行事务预提交。
  二、任何一个参与者反馈NO,或者等待超时后协调者尚没法收到全部参与者的反馈,即中断事务。
 
  事务预提交:(全部参与者均反馈YES时)
  一、协调者向全部参与者发出PreCommit请求,进入准备阶段。
  二、参与者收到PreCommit请求后,执行事务操做,将Undo和Redo信息记入事务日志中(但不提交事务)。
  三、各参与者向协调者反馈Ack响应或No响应,并等待最终指令。
 
  中断事务:(任何一个参与者反馈NO,或者等待超时后协调者尚没法收到全部参与者的反馈时)
  一、协调者向全部参与者发出abort请求。
  二、不管收到协调者发出的abort请求,或者在等待协调者请求过程当中出现超时,参与者均会中断事务。
 
  阶段3:do Commit
 
  此阶段也存在两种状况:
  一、全部参与者均反馈Ack响应,即执行真正的事务提交。
  二、任何一个参与者反馈NO,或者等待超时后协调者尚没法收到全部参与者的反馈,即中断事务。
 
  提交事务:(全部参与者均反馈Ack响应时)
  一、若是协调者处于工做状态,则向全部参与者发出do Commit请求。
  二、参与者收到do Commit请求后,会正式执行事务提交,并释放整个事务期间占用的资源。
  三、各参与者向协调者反馈Ack完成的消息。
  四、协调者收到全部参与者反馈的Ack消息后,即完成事务提交。
 
  中断事务:(任何一个参与者反馈NO,或者等待超时后协调者尚没法收到全部参与者的反馈时)
  一、若是协调者处于工做状态,向全部参与者发出abort请求。
  二、参与者使用阶段1中的Undo信息执行回滚操做,并释放整个事务期间占用的资源。
  三、各参与者向协调者反馈Ack完成的消息。
  四、协调者收到全部参与者反馈的Ack消息后,即完成事务中断。
 
  注意:进入阶段三后,不管协调者出现问题,或者协调者与参与者网络出现问题,都会致使参与者没法接收到协调者发出的do Commit请求或abort请求。此时,参与者都会在等待超时以后,继续执行事务提交。
 
  附示意图以下:
 
分布式一致性算法2PC和3PC
 3d

3PC的优势和缺陷

 
  优势:下降了阻塞范围,在等待超时后协调者或参与者会中断事务。避免了协调者单点问题,阶段3中协调者出现问题时,参与者会继续提交事务。
 
  缺陷:脑裂问题依然存在,即在参与者收到PreCommit请求后等待最终指令,若是此时协调者没法与参与者正常通讯,会致使参与者继续提交事务,形成数据不一致。
 日志

以上总结:

 
  2PC和3PC都还挺好理解,可是不管2PC或3PC,均没法完全解决分布式一致性问题。

htm

Google Chubby的做者Mike Burrows说过这个世界上只有一种一致性算法,那就是Paxos,其它的算法都是残次品!

介绍一下paxos的背景

Paxos算法是分布式技术大师Lamport提出的,主要目的是经过这个算法,让参与分布式处理的每一个参与者逐步达成一致意见。 用好理解的方式来讲,就是在一个选举过程当中, 让不一样的选民最终作出一致的决定。

Lamport为了讲述这个算法,假想了一个叫作Paxos的希腊成邦进行选举的情景,这个算法也是所以而得名。在他的假想中,这个城邦要采用民主提议和投票的方式选出一个最终的决议,但因为城邦的居民没有人愿意把所有时间和精力放在这种事情上,因此他们只能不定时的来参加提议,不定时来了解提议、投票进展,不定时的表达本身的投票意见。Paxos 算法的目标就是让他们按照少数服从多数的方式,最终达成一致意见。

 

首先咱们要先思考Paxos到底解决了什么问题?

 

先看看答案吧,简单来讲,paxos算法解决的就是一个最终一致性问题。假设一个集群有三个节点,Paxos可让三个节点更快的达成一致。由于在Paxos中规定,若是某个节点写操做执行以前其余两个节点(也就是大多数的节点)的值已经相等并记为V,那么除非此次写入的值也为V,不然操做不能进行。而当其余两个节点的意见不统一时,采用高编号的节点的值。所以,最终必定会达到三个节点意见统一的状态。

接下来就是文章正文,paxos的算法。接受者至关于决策者,提议者会给决策者发送信息!

 

Paxos算法的具体状况:

一、在整个提议和投票过程当中,主要的角色就是"提议者” (向”接受者”提出提议)和”接受者”(收到"提议者”的提议后,向”提议者”表达本身的意见)。

二、整个算法的大体过程为:

第一阶段:由于存在多个”提议者”,若是都提意见,那么“接受者”接受谁的不接受谁的?太混乱了。因此,要先明确哪一个"提议者”是意见领袖有权提出提议,将来,”接受者” 们就主要处理这个”提议者”的提议了(这样,也能够在提出提议时就尽可能让意见统一, 谋求尽早造成多数派)。

第二阶段:由上阶段选出的意见领袖提出提议,"接受者” 反馈意见。若是多数”接受者”接受了一个提议,那么提议就经过了。

 三、必需要了解的其余相关背景:

1)怎么明确意见领袖呢?经过编号。每一个"提议者”在第一阶段先报个号,谁的号大,谁就是意见领袖。若是很差理解,能够想象为贿选(文字下面为了方便表述,号越大的越有说话权,理解为贿赂的钱多)。每一个提议者先拿着钞票贿赂一圈”接受者”,谁给的钱多,第二阶段”接受者”就听谁的。(注: 这里和下文提到的”意见领袖”,并环是一个新的角色,而是表明在那一轮贿赂成功的"提议者”。因此,请把意见领袖理解为贿赂中胜出的"提议者”便可)

2)有个跟选举常识不同的地方,就是每一个”提议者”不会执着于让本身的提议经过,而是每一个”提议者”会执着于让提议尽快达成一致意见。 因此,为了这个目标,若是“提议者”在贿选的时候,发现”接受者”已经接受过前面意见领袖的提议了,即使”提议者”贿选成功,也会默默的把本身的提议改成前面意见领袖的提议。因此一旦贿赂成功,胜出的”提议者”再提出提议,提议内容也是前面意见领袖的提议(这样,在谋求尽早造成多数派的路上,又前进了一步)。

3)钱的多少很重要,若是钱少了,不管在第一,仍是第二阶段“接受者”都不会尿你,直接拒绝。

4)上面2)中讲到,若是"提议者”在贿选时,发现前面已经有意见领袖的提议,那就将本身的提议默默改为前面意见领袖的提议。这里有一种状况,若是你是“提议者”, 在贿赂的时候,”接受者1”跟你说”他见过的意见领袖的提议是案1”,而”接受者2”跟你说“他见过的意见领袖提议是方案2”,你该怎么办?这时的原则也很简单,仍是:钱的多少很重要!你判断一下是”接受者1”见过的意见领袖有钱,仍是”接受者2”见过的意见领袖有钱?如何判断呢?由于”接受者”在被“提议者”贿赂的时候,本身会记下贿赂的金额。因此当你贿赂”接受者”时,- -一旦你给的贿赂多而胜出,”接受者” 会告诉你两件事情: a.前任意见领袖的提议内容(若是有的话),b.前任意见领袖当时贿赂了多少钱。这样,再面对刚才的情景时,你只须要判断一下"接受者1”和"接受者2”告诉你的信息中,哪一个意见领袖当时给的钱多,那你就默默的把本身的提议,改为那个意见领袖的提议。

 5)最后这一部分最有意思,但描述起来有点绕,若是不能一会儿就理解能够先看后面的例子。在整个选举过程当中,每一个人谁先来谁后到,”接受者” 什么时间可以接到"提议者”的信息,彻底不可控的。因此极可能一个意见领袖已经产生了 ,可是因为这个意见领袖的第一阶段刚刚开始, 绝大部分"接受者”尚未收到这个意见领袖的提议。结果,这时忽然冲进来了一个新的土豪"提议者”,那么这个土豪"提议者”也是有机会让本身的提议胜出的!这时就造成了一种博弈: a. 上一个意见领袖要赶在土豪”提议者”贿赂到”接受者”前,赶到”接受者”面前上他接受本身的提议,不然会由于本身的以前贿赂的钱比土豪少而被拒绝。b.土豪"提议者”要赶在上一个意见领袖将提议传达给“接受者”前,贿赂到”接受者”,不然土豪”提议者”即使贿赂成功,也要默默的将本身的提议改成前任意见领袖的提议。这整个博弈的过程,最终就看这两个”提议者”谁的进展快了。但最终必定会有一个意见领袖,先获得多数"接受者”的承认,那他的提议就胜出了。

四、总结

好啦,故事到这里基本讲述完了,我们来总结一下,其实Paxos算法就下面这么几个原则:

1) Paxos算法包括两个阶段:第一个阶段主要是贿选,尚未提出提议;第二个阶段主要根据第一阶段的结果,明确接受谁的提议,并明确提议的内容是什么(这个提议多是贿选胜出“提议者”本身的提议,也多是前任意见领袖的提议,具体是哪一个提议,见下面第3点原则)。

2)编号(贿赂金额)很重要,不管在哪一个阶段,编号(贿赂金额)小的,都会被鄙视(被拒绝)。3)在第一阶段中,一旦"接受者”已经接受了以前意见领袖的提议,那后面再来找这个”接受者”的”提议者”,即使在贿赂中胜出,也要被洗脑,默默将本身的提议改成前任意见领袖的提议,而后他会在第二阶段提出该提议(也就是以前意见领袖的提议,以力争让你们的意见趋同)。若是"接受者”以前没有接受过任何提议,那贿选胜出的"提议者”就能够提出本身的提议了。

 五、举例

最后举个例子,加深一下印象:
有两个”提议者”和三个”接受者” 。
1)首先"提议者1”贿赂了3个"接受者”

 

 

2) 3个"接受者”记录下贿赂金额,由于目前只有一个"提议者”出价,所以$1就是最高的了,因此"接受者”们返回贿赂成功。此外,由于没有任何先前的意见领袖提出的提议,所以"接受者”们告诉"提议者1”没有以前接受过的提议(天然也就没有上一个意见领袖的贿赂金额了)。

 

3) “提以者1"向“接受者1”提出了本身的提以: 1号提以,并告知本身以前已賄賂$1。

 

4)“接受者1” 检查了一下,目前记录的贿赂金额就是$1,因而接受了这一提议, 并把1号提议记录在案。

 

 

 

 

5)在”提议者1”向"接受者2” "接受者3”发起提议前,土豪“提议者2”出现,他开始用$2贿赂”接受者1”与”接受者2”。

 

6) “接受者1”与"接受者2”马上被收买,将贿赂金额改成$2。可是,不一样的是: ”接受者1"告诉“提议者2”,以前我已经接受过1号提议了,同时1号提议的”提议者”贿赂过$1;而,"接受者2”告诉”提议者2”,以前没有接受过其余意见领袖的提议,也没有上一个意见领袖的贿赂金额。

 

7)这时, “提议者1”回过神来了,他向"接受者2”和”接受者3”发起1号提议,并带着信息”我前期已经贿赂过$1”。

8) ”接受者2” "接受者3”开始答复: ”接受者2”检查了一下本身记录的贿赂金额,而后表示,已经有人出价到$2了,而你以前只出到$1,不接受你的提议,再见。但”接受者3”检查了一下本身记录的贿赂金额,目前记录的贿赂金额就是$1,因而接受了这一提议,并把1号提议记录在案。

 

9)到这里, ”提议者1”已经获得两个接受者的赞同,已经获得了多数"接受者”的赞同。因而”提议者1”肯定1号提议最终经过。

 


10) 下面,回到"提议者2”。刚才说到, ”提议者2”贿赂了”接受者1”和"接受者2”,被“接受者1”告知: "以前已经接受过1号提议了,同时1号提议的'提议者’贿赂过$1”,并被”接受者2”告知: "之 前没有接到过其余意见领袖的提议,也没有其余意见领袖的贿赂金额”。这时"提议者2”,拿到信息后,判断一下,目前贿赂过最高金额(即$1)的提议就是1号提议了,因此“提议者2”默默的把本身的提议改成与1号提议一致,而后开始向”接受者1””接受者2” 发起提议(提议内容仍然是1号提议),并带着信息:以前本身已贿赂过$2。

 

11) 这时”接受者1” ”接受者2”收到”提议者2”的提议后,照例先比对一下贿赂金额,比对发现”提议者2”以前已贿赂$2,而且本身记录的贿赂金额也是$2,因此接受他的提议,也就是都接受1号提议。

 

这里再多说一句:

回到上面的第5)步,若是”提议者2”第一次先去贿赂"接受者2”"接受者3” 会发生什么?那极可能1号提议就不会成为最终选出的提议。由于当”提议者2”先贿赂到了”接受者2””接受者3”,那等“提议者1” 带着议题再去找这两位的时候,就会由于以前贿赂的钱少($1<$2)而被拒绝。因此,这也就是刚才讲到可能存在博弈的地方: a.”提议者1”要赶在“提议者2”贿赂到"接受者2””接受者3” 以前,让”接受者2””接受者3” 接受本身的意见,不然”提议者1”会由于钱少而被拒绝; b.”提议者2”要赶在“提议者1”以前贿赂到”接受者”,不然”提议者2”即使贿赂成功,也要默默的将本身的提议改成“提议者1” 的提议。但你日后推演会发现,不管如何,总会有一个“提议者”的提议得到多数票而胜出。

以上,只是把大体的Paxos算法的思路介绍了一下,由于情景实在太复杂,好比: “提议

者”、 “接受者”若是是4个、5..... 好比: "提议者”与”接受者”之间的交互谁先谁后,等等各种状况。可是,其实都是可以严谨的推导出最后可以选出一个多数派的,不过篇幅就会太长了。你们有兴趣能够按照上面的思路,本身再模拟模拟"提议者”“接受者” 数量或多或少,交互或先或后的各类状况,结果确定是最终惟一一个 提议会得到多数票而胜出。

回想当时本身看Paxos算法时,过不少的弯路,花了很长时间,这篇文章也是结合本身看Paxos算法时的一些心得所写,但愿对初学者能有些启发。

 

参考网址:

https://www.zhihu.com/question/19787937

https://blog.csdn.net/zifanyou/article/details/84789022

https://www.cnblogs.com/esingchan/p/3917718.html

https://www.cnblogs.com/hugb/p/8955505.html

相关文章
相关标签/搜索