天天看点

Paxos算法讲解

Paxos算法解决的问题是在一个消息可能会发生延迟、丢失、重复的分布式系统中 如何就某个值达成一致,保证不论发生以上任何异常,都不会破坏值的一致性。

基于一大堆完全不可靠的网络条件下,可靠确定地实现共识一致性的算法

       Paxos算法是这样解决这个问题:

       1、每个人都可以提出建议、同意建议、接受建议

       2、少数服从多数。只要建议被多数人同意即可确定该建议。

       于是确定以下讨论方式:

       1、只有被提出来的建议才能被大家同意。

       2、最终只能确定一个建议

       3、如果某个人认为大家同意了某个建议,那么这个建议必须真的是被大家同意的

P1:每一个人必须同意他收到的第一个建议

P2:一个提议必须被大多数人同意才能生效

一个人可以同时同意多个建议(可能会出现拜占庭将军问题导致结果不一致)(拜占庭:存在消息丢失的不可靠信道上试图通过消息传递的方式达到一致性是不可能的,因为Paxos必须假定信道是可靠的,即消息不会被篡改。消息丢失是允许的)

P3:一个人一旦同意了某个建议,那么之后同意的建议内容信息必须一致。

必须为提议分配一个编号,在提议之间建立一个全序关系

Paxos完成一次写操作需要两次来回,分别是prepare/promise, 和 propose/accept:

Paxos算法讲解

第一次由提交者Leader向所有其他服务器发出prepare消息请求准备,所有服务器中大多数如果回复诺言承诺就表示准备好了,可以接受写入;第二次提交者向所有服务器发出正式建议propose,所有服务器中大多数如果回复已经接收就表示成功了。

Paxos读操作

客户端请求读取所有进程中存储的当前值,如果客户端获得大多数节点返回的相同的值,它就算读取成功了,将保存这个读结果

在现实中使用Paxos实现时,其实不需要每个节点都进行一次读取,会有更好的读取方式,但是他们都是拓展的原始 Paxos 算法。

Paxos写操作(Paxos精华)

Paxos管理的系统中一个客户端要求写入一个新值时,Paxos能保证客户端发送写请求到Paxos集群中任何成员。注意这里是任何成员,意味着没有任何单点风险,Paxos系统能够一直保持在线可用(有节点宕机或掉线不发给它就是了)(如果我们像二阶段或三阶段提交那样设置一个协调者,那么免不了会有单点故障的风险,Paxos使用多客户端共同管理的方式解决了三阶段提交中,协调者在doCommit阶段发送rebort,由于网络导致没能到达参与者,而参与者自动执行commit导致数据不一致的问题,具体详细在下面描述)

当客户端的写请求被Paxos系统接收后,Paxos进程会将这个写的新值放到系统中的请求“建议”。

这个准备消息保存在被建议的值数据中,也称为序列号,序列号是由建议进程产生的,它表明新旧建议之间的区别。此时建议进程将产生一个seq

Paxos第一阶段:准备prepare/承诺promise

准备阶段就是将建议值发送到各个目标节点。

当建议被发到目标节点后,进程会会检查建议中的序列号,是否是它们见到过的最新,如果是最新,它们会发出一个promise不再接受比这个新序列号更旧的建议了,这个诺言promise作为消息从许下诺言的进程发到提交建议新值的进程服务器,这个诺言消息给提交建议的进程后,提交建议的进程需要自己统计一下有多少其他进程已经发回它们的诺言promise了,如果数量过半,那么这个提交建议的进程就能知道它获得了发言权(因为有大多数支持),进入第二阶段,否则表示失败,即客户端要求的写操作失败

Paxos算法讲解

第二阶段:Paxos接纳Acceptance,propose/accept

一旦建议提交者已经从大多数其他进程服务器获得了诺言,它会要求许诺的进程服务器接收它们之前承诺接受的新值数据,这是一个“确认commit”阶段,如果没有冲突建议 失败或分区错误,那么这个新建议将被所有其他节点接受,那么Paxos过程就完成了。

案例解释:有三个客户端向Paxos系统发出写操作

假设:只有User1、User2、User3 三个人决定1+1等于几!

  1. 准备阶段
Paxos算法讲解

 1、User1  提案编号为1 并发送给User2和User3。

因User2 和User3 根据P2c它们并没有接受过小于编号为1的提案。所以它们可以接受该提议,并反馈给User1 不再接受小于编号1的提案。这时User1收到多数人的回复,将进入第2阶段。(如果收到的回复并不能形成多数人,那么将再次进入阶段1)

 2、User2 提案编号为2  ;并发送给User1和User3。

      因User1第一次收到提案,并且根据P2C它并没有同意过小于编号为2的提议,所以它可以接受该提议。User3由于接受过User1编号为1的提案,但User2的提案编号2>1所以User3也可以同意User2的提议,并反馈不再接受小于2的提议。User2也收到多数人的回复,将进行第2阶段。

  1. User3提案编号为3 ;并发送给user1 和user2 .

因user1收到user3编号为3的提案>user2编号为2的提案,所以接受user3的提案。

因user2收到User3编号为3的提案>user1 编号为1的提案,所以接受user3的提案。

至此user3也收到多数人回复,将进行第2阶段。

第二阶段:propose/accept

 1、user1 发送编号为1的提议,提议内容为:1+1=1;并发送给user2和User3 。

      由于user2已经声明不再接受小于3的提案,所以拒绝user1的提案。

      由于User3已经声明不再接受小于2的提案,所以同样拒绝User1的提案。

      User1提议被多数人拒绝,再次进入阶段1.

2、user2 发送编号为2的提议,提议内容为:1+1=2;并发送给User1和User3

由于User1已经声明不再接受小于3的提案,所以拒绝user2的提议。

      由于User3已经声明不再接受小于2的提案,该提案编号=2所以user3同意User2的提议。

      但User2并没有获得多数人的同意,所以同样进行阶段1.

  1. User3 发送编号为3的提议,提议内容为:1+1=3;并发送给User1和User2;

由于user1声明不再接受小于3的提案,所以同意User3的提议。

 由于 user2声明不再接受小于3的提案,所以同意User3的提议。

 至此最终User3可以获得多数人的同意。

Paxos算法讲解

参考链接:

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

http://blog.51cto.com/12615191/2086264

继续阅读