Basic Paxos
在Basic Paxos中,使用提案代表一个提议,在提案中除了提案编号,还包含了提议值。使用[n, v]表示一个提案,其中n为提案编号,v为提议值。
整个共识协商是分2个阶段进行的(二阶段提交)。假设客户端1的提案编号为1,客户端2的提案编号为5,节点A、B先收到来自客户端1的准备请求,节点C先收到来自客户端2的准备请求。
prepare阶段
客户端1、2作为提议者,分别向所有接受者发送包含提案编号的准备请求:
对于客户端1的提案,由于之前没有通过任何提案,所以节点A、B以后将不再响应提案编号小于等于1的prepare请求,即不会通过编号小于1的提案,节点C以后不再响应提案编号小于等于5的准备请求,即不会通过编号小于5的提案;
对于客户端2的提案,当节点A、B收到提案编号为5的准备请求的时候,因为提案编号5大于它们之前响应的准备请求的提案编号1,而且两个节点都没有通过任何提案,所以它将返回一个 “尚无提案”的响应,所以节点A、B将不再响应提案编号小于等于5的准备请求,即不会通过编号小于5的提案, 当节点C收到提案编号为1的准备请求的时候,由于提案编号1小于它之前响应的准备请求的提案编号5,所以丢弃该准备请求不做响应;
Accept阶段
首先客户端1、2在收到大多数节点的准备响应之后,会分别发送接受请求:
当客户端1收到大多数的接受者(节点A、B)的准备响应后,根据响应中提案编号最大的提案的值设置接受请求中的值。因为节点A、B的准备响应中都为空,所以就把自己的提议值3作为提案的值,发送接受请求[1, 3];
当客户端2收到大多数的接受者的准备响应后(节点A、B和节点C),根据响应中提案编号最大的提案的值,来设置接受请求中的值。因为该值在来自节点A、B、C的准备响应中都为空,所以就把自己的提议值7作为提案的值,发送接受请求[5, 7];
当三个节点收到2个客户端的接受请求时:
当节点A、B、C收到接受请求[1, 3]的时候,由于提案的提案编号1小于三个节点承诺能通过的提案的最小提案编号5,所以提案[1, 3]将被拒绝;
当节点A、B、C收到接受请求[5, 7]的时候,由于提案的提案编号5不小于三个节点承诺能通过的提案的最小提案编号5,所以就通过提案[5, 7],也就是接受了值7,三个节点就X值为7达成了共识;
Multi-Paxos
Basic Paxos只能就单个值(Value)达成共识,Multi-Paxos是通过多个Basic Paxos实例实现一系列值的共识的算法。
Multi-Paxos通过引入Leader节点,将Leader节点作为唯一提议者,避免了多个提议者同时提交提案的情况,解决了提案冲突的问题, Leader节点是通过执行Basic Paxos算法,进行投票选举产生的。
优化Basic Paxos执行可以采用“当领导者处于稳定状态时,省掉准备阶段,直接进入接受阶段”这个优化机制。在Leader节点上,序列中的命令是最新的,不再需要通过准备请求来发现之前被大多数节点通过的提案,Leader可以独立指定提案中的值。Leader节点在提交命令时,可以省掉准备阶段,直接进入到接受阶段: