Paxos算法
为什么需要Paxos算法?
Paxos算法是基于“消息传递”(另一种为“共享内存”)来解决一致性问题。eg:在一个分布式数据库系统中,如果各节点的初始状态一致,每个节点都执行相同的操作序列,那么他们最后得到一个一致性状态。为了保证每个序列都执行相同的操作序列,需要在每一条指令上执行一个“一致性算法”以保证每个节点看到的指令一致。比较囧的是我现在纠结的这个算法是别人30年前想出来的。
Paxos的算法描述一般都是一个“Paxos”的小岛上通过决议的问题,该问题中包括三个角色(proposers、accepter、learners):
- value只有被proposers提出来之后才能被批准;
- 在一次Paxos执行实例中只有一个value能被批准;
- learners只能获得被批准的value。
下面就开始考虑如何才能实现:
- (P1) 一个accepter只能批准它接收到的第一个value;
- (P1a)当且仅当批准者没有接收到编号大于n的提案请求时才批准编号为n的提案。
- (P2) 如果一个value被通过,那么之后通过的value必须和这个value一致;
- (P2a)如果一个value被通过,那么之后任何accepter再批准的value必须是value;
- (P2b)如果一个value被通过,那么之后proposers提出的value必须具有value值;
- (P2c)如果一个value被通过,那么存在一个多数派,要么没有批准过任何编号小于n的value,要么进行的最后一次批准的值为value。
Paxos算法的基本流程,首先是Prepare阶段:
- proposers选择一个提案编号n,并将prepare请求发送给accepter中的一个多数派;
- accepter接到prepare请求后,如果prepare的编号大于它已回复的所有prepare消息,则accepter将自己上次批准的回复回复给提案者。
然后是批准阶段:
- proposer接到多数派accepter的回复后进入批准阶段,proposer向有回复的accepter发送批准请求;
- 在不违背自己向其他人proposer的承诺的前提下,accepter收到批准请求后随即批准这个请求。
如果我接收到一个“邀请”去参加一个投票,但是我接收的最后一次投票的id比该“邀请”的id大,那么就说明我正在参加一个更新的投票,你邀请的“投票”我可能已经参加过了就不去了。如果没有参加过就记录下这次的id,并把“上次投票的round值”和“相应的value值”返回给你。然后你发给我一个value值让我批准,这样我在第i轮把票投给v,并且这时我是我参加的最新的一次邀请并且是我没有投过的一次,那么我就把值投给v。然后告诉大家我投票的结果。
但是,如果要求我在第i轮把票投给v的时候我已经开始一个更新的投票了(或者我以前已经投过了)那就无视它。这时,那些等着的人如果发现我们投的票已经超过半数了,那就宣布已经知道结果了,并宣布这个结果。
现在还有就是产生这些value让我们选?如果通过邀请过程发现一个“多数派”都没有投过票,那我就随便选出一个value让你们投票。如果发现了已经有人投票了,那就选出投过票的round id最大的那个value作为这个round的要投票的值。这种做法是为了保证:“对于任何的round j,其中j<i。除了v之外,其他的value都不可能被通过”。保证了这个就可以使得在不同round中选出的value是相同的。
---------------------------------
个人理解,欢迎拍砖。