vlambda博客
学习文章列表

分布式架构设计-06 分布式算法paxos

0 算法背景

Paxos算法是莱斯利·兰伯特(Leslie Lamport)于1990年提出的一种基于消息传递的一致性算法。自从该算法被提出后,它基本上是分布式共识的代名词,因为当前最常用的一批共识算法都是基于它改进的。比如,Fast Paxos 算法、Cheap Paxos 算法、Raft 算法、ZAB 协议等等。Google的很多大型分布式系统都采用了Paxos算法来解决分布式一致性问题,如Chubby、Megastore以及Spanner等。还有我们熟悉的动物管理员ZooKeeper,MySQL 5.7推出的MySQL Group Replication等纷纷采用Paxos算法解决分布式一致性问题。本篇主要介绍basic paxos。

1 三种角色

在 Basic Paxos 中,有提议者(Proposer)、接受者(Acceptor)、学习者(Learner)三种角色,一个节点可以身兼多个角色。

  • 提议者:提议一个值,用于投票表决。

  • 接受者:对每个提议的值进行投票,并存储接受的值, 一般来说,集群中的所有节点都在扮演接受者的角色,参与共识协商,并接受和存储数据。

  • 学习者:被告知投票的结果,接受达成共识的值,存储保存,不参与投票的过程。相当于是数据备份节点。

2 如何达成共识

提案包含提案编号和提议值,形如[pid,value],其中value可以为空,提议者在提交提案时,可以不指定value。整个共识分为两个阶段完成,一个是准备(prepare)阶段,另一个是接受(accept)阶段,具体过程如何协商,我们通过例子来说明。

2.1 准备阶段,一个提议者向三个接受者提交了编号为1,value为空的提案[1,];

2.2 对于接受者A,B,C来说,之前没有通过任何提案,所以A,B,C都返回尚无提案的响应,并承若之后不会再接受提案编号小于等于1的提案,也就是只接受最大编号的提案;

2.3 提议者得到了大多数接受者响应,于是进入接受阶段,提交提案[1,x=5],接受者通过,共识达成;

3 多提案的情况

上述情况是一种理想情况,实际情况是同时会有多个提案,并且接受者有可能存在宕机的情况。

3.1 准备阶段,有两个提议者分别先后提交了提案[2,]和[5,];

3.2 对于提议者1,因为A和B之前没有通过任何提案,所以A,B返回给他尚无提案的响应,C宕机,这时A和B保存的准备提案为[2,];

3.3 对于提案2,A和B接收到了编号大于之前编号为2的提案,而且两个节点都没有通过任何提案,所以它们将返回一个 “尚无提案”的响应,并承诺以后不再响应提案编号小于等于 5 的准备请求,不会通过编号小于 5 的提案,这时C也恢复了,所以提议者2得到A,B,C都返回尚无提案的响应;

3.4 接受阶段,由于提议者1和2都收到了大多数接受者提案,所以开始发起接受提案,提议者1[2,x=6],提议者2[5,x=7];

3.5 当节点 A、B、C收到接受请求[2,x=6]的时候,由于提案的提案编号2小于三个节点承诺能通过的提案的最小提案编号 5,所以提案[2,x=6]将被拒绝;

3.6 当节点 A、B、C收到接受请求[5,x=7]的时候,由于提案的提案编号 5 不小于三个节点承诺能通过的提案的最小提案编号 5,所以就通过提案[5, x=7],三个节点就X=7达成了共识;

3.7 当接受者通过了一个提案时,就通知给所有的学习者。当学习者发现大多数的接受者都通过了某个提案,那么它也通过该提案,接受该提案的值。

4 内容小结

4.1 paxos采用二阶段提交的方式来达成共识;

4.2 paxos实现了容错,在网络节点半数以上正常情况下能正常工作;

4.3 提案编号代表优先级,有序增大,接受者要有三个承诺:

  • 如接受者已经响应过一个准备请求编号n,那么在收到一个新的准备请求后,如果该编号小于等于n,将不再响应该提案;

  • 如果接受者已经响应过一个准备请求编号n,在接收到一个接受请求后,如果该请求编号小于n,则接受者将拒绝该提案;

  • 如果接受者之前有通过提案,那么接受者将承诺,会在准备请求的响应中,包含已经通过最大编号的提案信息;