知之为知之,不知为不知,是知也!
今天学习zookeeper涉及到了其中的paxos算法,抽空研究了一下paxos算法是如何进行选举的!
角色
-
Proposer提议者:负责提出议案,也就是value(vaue是paxos协议中将操作统一抽象为value)。
-
Acceptor批准者:负责处理proposer提出的议案,proposer提出的议案必须获得半数以上的acceptor的批准才能通过。
-
Learner学习者:不参与选举,主要参数相关的状态同步流程。
选举流程
流程图如下:
具体流程如下:
-
1、Proposer生成唯一id(proposalID),然后携带自己的proposalID向acceptor发送prepare请求。
-
2、Acceptor收到prepare请求,判断proposalID是否比之前已响应的所有提案的proposalID大。
-
如果是,则本地持久化proposalID,然后将proposalID填充到max_proposalid中,然后回复请求,并且携带proposalID的value(第一次会为空),并且不会接受小于proposalID的提案了。
-
如果否,则不回复或者回复Error
-
-
3、经过一段时间Proposer收到一些prepare回复
-
如果回复超过一半,且回复的value都为空,则Proposer发出accept请求,并带上自己的value(也就是自己要当选Leader了)。
-
如果回复超过一半,且value不为空,则Proposer发出accept请求,并带上回复中的proposalID最大的value作为自己提案内容。
-
若回复数量小于一半,则尝试更新生成更大的proposaID,然后返回准备阶段重新执行。
-
-
4、Acceptor收到accept请求后会做出以下判断
-
如果收到的proposalID>=持久化的max_proposalid,则回复给Proposer提交成功,然后持久化proposalID和value。
-
若收到的proposalID<max_proposalid,则不回复或者回复提交失败。
-
-
5、过一段时间后Proposer收集到一些accept回复
-
如果回复数量超过一半的Acceptor数量,那么提交value成功,此时发送一个广播给所有的Proposer、Learner。通知他们已经提交的value。
-
如果回复数量<=一半的Acceptor数量,那么再尝试更新更大的proposalID,然后转到准备阶段。
-
如果收到提交失败的回复,则也尝试更新更大的proposalid,也转到准备阶段。
-
总结
从以上的流程中可以看到Proposer会发出prepare和accept两次请求,
第一次的prepare请求主要是为了找出proposalID最大的Proposer,
第二次的accept请求主要是为了将proposalID最大的Proposer的value发送给所有的Proposer和Learner。