分布式一致性算法-paxos详解与分析

431 阅读3分钟

一、Paxos算法背景

Paxos算法是Lamport宗师提出的一种基于消息传递的分布式一致性算法,使其获得2013年图灵奖。

Paxos由Lamport于1998年在《The Part-Time Parliament》论文中首次公开,最初的描述使用希腊的一个小岛Paxos作为比喻,描述了Paxos小岛中通过决议的流程,并以此命名这个算法,但是这个描述理解起来比较有挑战性。后来在2001年,Lamport觉得同行不能理解他的幽默感,于是重新发表了朴实的算法描述版本《Paxos Made Simple》。

自Paxos问世以来就持续垄断了分布式一致性算法,Paxos这个名词几乎等同于分布式一致性。Google的很多大型分布式系统都采用了Paxos算法来解决分布式一致性问题,如Chubby、Megastore以及Spanner等。开源的ZooKeeper,以及MySQL 5.7推出的用来取代传统的主从复制的MySQL Group Replication等纷纷采用Paxos算法解决分布式一致性问题。

然而,Paxos的最大特点就是难,不仅难以理解,更难以实现

二、Paxos算法流程

Paxos:多数派决议(最终解决一致性问题)

三种角色:

Proposer:提交者(议案提交者)

                 提交议案(判断是否过半),提交批准议案(判断是否过半)

Acceptor:接收者(议案接收者)

                 接受议案或者驳回议案,给proposer回应(promise)

Learner:学习者(打酱油的)

                 如果议案产生,学习议案。
**设定****1:**如果Acceptor没有接受议案,那么他必须接受第一个议案
**设定****2:**每个议案比必须有一个编号,并且编号只能增长,不能重复。越往后越大。
**设定****3:**接受编号大的议案,如果小于之前接受议案编号,那么不接受
**设定****4:**议案有2种(提交的议案,批准的议案)

1.Prepare阶段(决议提交) 

a)Proposer希望议案V。首先发出Prepare请求至大多数Acceptor。Prepare请求内容为序列号K 

b)Acceptor收到Prepare请求为编号K后,检查自己手里是否有处理过Prepare请求。 

c)如果Acceptor没有接受过任何Prepare请求,那么用OK来回复Proposer,代表Acceptor必须接受收到的第一个议案(设定1) 

d)否则,如果Acceptor之前接受过任何Prepare请求(如:MaxN),那么比较议案编号,如果K<MaxN,则用reject或者error回复Proposer 

e)如果K>=MaxN,那么检查之前是否有批准的议案,如果没有则用OK来回复Proposer,并记录K 

f)如果K>=MaxN,那么检查之前是否有批准的议案,如果有则回复批准的议案编号和议案内容(如:<AcceptN, AcceptV>, AcceptN为批准的议案编号,AcceptV为批准的议案内容)

2.Accept阶段(批准阶段)  

a)Proposer收到过半Acceptor发来的回复,回复都是OK,且没有附带任何批准过的议案编号和议案内容。那么Proposer继续提交批准请求,不过此时会连议案编号K和议案内容V一起提交(<K, V>这种数据形式)  

b)Proposer收到过半Acceptor发来的回复,回复都是OK,且附带批准过的议案编号和议案内容(<pok,议案编号,议案内容>)。那么Proposer找到所有回复中超过半数的那个(假设为<pok,AcceptNx,AcceptVx>)作为提交批准请求(请求为<K,AcceptVx>)发送给Acceptor。

 c)Proposer没有收到过半Acceptor发来的回复,则修改议案编号K为Kx,并将编号重新发送给Acceptors(重复Prepare阶段的过程)

 d)Acceptor收到Proposer发来的Accept请求,如果编号K<MaxN则不回应或者reject。

e)Acceptor收到Proposer发来的Accept请求,如果编号K>=MaxN则批准该议案,并设置手里批准的议案为<K,接受议案的编号,接受议案的内容>,回复Proposer。

 f)经过一段时间Proposer对比手里收到的Accept回复,如果超过半数,则结束流程(代表议案被批准),同时通知Leaner可以学习议案。

 g)经过一段时间Proposer对比手里收到的Accept回复,如果未超过半数,则修改议案编号重新进入Prepare阶段。