ZooKeep干货|分布式核心原理Paxos算法

Paxos算法是1990年由莱斯利·兰伯特提出的共识算法,为分布式系统中达成一致提供解决方案。它描述了一个在议员可能缺席的情况下,如何确保决议一致性的过程。Paxos算法分为Prepare和Accept两个阶段,确保提案的唯一性和一致性。尽管复杂,但其思想启发了诸如Raft和ZAB等更易于实施的算法。
摘要由CSDN通过智能技术生成

大家可能在各个场合都听说过Paxos协议,毕竟这个开创性的协议是很多分布式协议的鼻祖,比如比较有名的Raft协议、zookeeper使用的zab算法就是基于Paxos协议发展而来的。在面试过程中,面试官也可能会考察你对分布式的了解,其中就很有可能会让你谈谈对Paxos的理解。本文尝试探究推到paxos算法是如何提出的,通过一步步推导带你揭开Paxos神秘的面纱。

一、Paxos产生背景

Paxos算法是莱斯利·兰伯特于1990年提出的一种基于消息传递且具有高度容错特性的共识(consensus)算法。需要注意的是,Paxos常被误称为“一致性算法”。但是“一致性(consistency)”和“共识(consensus)”并不是同一个概念。Paxos是一个共识(consensus)算法。

Paxos算法解决的是一个分布式系统如何就某个值(决议)达成一致。它晦涩难懂的程度完全可以跟它的重要程度相匹敌。一个典型的场景是,在一个分布式数据库系统中,如果各个节点的初始状态一致,每个节点执行相同的操作序列,那么他们最后能够得到一个一致的状态。为了保证每个节点执行相同的命令序列,需要在每一条指令上执行一个“一致性算法”以保证每个节点看到的指令一致。

 

二、共识性问题

2.1 算法的提出和推导

为描述Paxos算法,Lamport虚拟了一个叫做Paxos的希腊城邦,这个岛按照议会民主制的政治模式制订法律,但是没有人愿意将自己的全部时间和精力放在这种事情上。所以无论是议员,议长或者传递纸条的服务员都不能承诺别人需要时一定会出现,也无法承诺批准决议或者传递消息的时间。但是这里假设没有拜占庭将军问题(Byzantine failure,即虽然有可能一个消息被传递了两次,但是绝对不会出现错误的消息);只要等待足够的时间,消息就会被传到。另外,Paxos岛上的议员是不会反对其他议员提出的决议的。

而拜占庭将军问题被认为是容错性问题中最难的问题类型之一,在此处不予考虑。

首先将议员的角色分为 proposers,acceptors,和 learners(允许身兼数职)。proposers 提出提案,提案信息包括提案编号和提议的 value;acceptor 收到提案后可以接受(accept)提案,若提案获得多数派(majority)的 acceptors 的接受,则称该提案被批准(chosen);learners 只能“学习”被批准的提案。划分角色后,就可以更精确的定义问题,并有以下三种约束:

  • 决议(value)只有在被 proposers 提出后才能被批准(未经批准的决议称为“提案(proposal)”);
  • 在一次 Paxos 算法的执行实例中,只批准(chosen)一个 value;
  • learners 只能获得被批准(chosen)的 value。

 

批准 value 的过程中,首先 proposers 将 value 发送给 acceptors,之后 acceptors 对 value 进行接受(accept)。为了满足只批准一个 value 的约束,要求经“多数派(majority)”接受的 value 成为正式的决议(称为“批准”决议)。这是因为无论是按照人数还是按照权重划分,两组“多数派”至少有一个公共的 acceptor,如果每个 acceptor 只能接受一个 value,约束2就能保证。

 

于是产生了一个显而易见的新约束:

P1:一个 acceptor 必须接受(accept)第一次收到的提案。

注意 P1 是不完备的。如果恰好一半 acceptor 接受的提案具有 value A,另一半接受的提案具有 value B,那么就无法形成多数派,无法批准任何一个 value。

约束2并不要求只批准一个提案,暗示可能存在多个提案。只要提案的 value 是一样的,批准多个提案不违背约束2。于是可以产生约束 P2:

P2:一旦一个具有 value v 的提案被批准(chosen),那么之后批准(chosen)的提案必须具有 value v。

注:通过某种方法可以为每个提案分配一个编号,在提案之间建立一个全序关系,所谓“之后”都是指所有编号更大的提案。

如果 P1 和 P2 都能够保证,那么约束2就能够保证。

批准一个 value 意味着多个 acceptor 接受(accept)了该 value。因此,可以对 P2 进行加强:

P2a:一旦一个具有 value v 的提案被批准(chosen),那么之后任何 acceptor 再次接受(accept)的提案必须具有 value v。

由于通信是异步的,P2a 和 P1 会发生冲突。如果一个 value 被批准后,一个 proposer 和一个 acceptor 从休眠中苏醒,前者提出一个具有新的 value 的提案。根据 P1,后者应当接受,根据 P2a,则不应当接受,这种场景下 P2a 和 P1 有矛盾。于是需要换个思路,转而对 proposer 的行为进行约束:

P2b:一旦一个具有 value v 的提案被批准(chosen),那么以后任何 proposer 提出的提案必须具有 value v。

由于 acceptor 能接受的提案都必须由 proposer 提出,所以 P2b 蕴涵了 P2a,是一个更强的约束。

但是根据 P2b 难以提出实现手段。因此需要进一步加强 P2b。

假设一个编号为 m 的 value v 已经获得批准(chosen),来看看在什么情况下对任何编号为 n(n>m)的提案都含有 value v。因为 m 已经获得批准(chosen),显然存在一个 acceptors 的多数派 C,他们都接受(accept)了v。考虑到任何多数派都和 C 具有至少一个公共成员,可以找到一个蕴涵 P2b 的约束 P2c:

P2c:如果一个编号为 n 的提案具有 value v,该提案被提出(issued),那么存在一个多数派,要么他们中所有人都没有接受(accept)编号小于 n 的任何提案,要么他们已经接受(accept)的所有编号小于 n 的提案中编号最大的那个提案具有 value v。

2.2 算法的内容

经过上面的推导,我们总结下Paxos算法的流程。

Paxos算法分为两个阶段。具体如下:

阶段一:

1.Proposer选择一个提案编号N,然后向半数以上的Acceptor发送编号为N的Prepare请求。

2.如果一个Acceptor收到一个编号为N的Prepare请求,且N大于该Acceptor已经响应过的所有Prepare请求的编号,那么它就会将它已经接受过的编号最大的提案(如果有的话)作为响应反馈给Proposer,同时该Acceptor承诺不再接受任何编号小于N的提案。

阶段二:

1.如果Proposer收到半数以上Acceptor对其发出的编号为N的Prepare请求的响应,那么它就会发送一个针对[N,V]提案的Accept请求给半数以上的Acceptor。注意:V就是收到的响应中编号最大的提案的value,如果响应中不包含任何提案,那么V就由Proposer自己决定。

2.如果Acceptor收到一个针对编号为N的提案的Accept请求,只要该Acceptor没有对编号大于N的Prepare请求做出过响应,它就接受该提案。

三、Paxos算法三种可能的情况

情况1:提案已接受

X、Y代表客户端,S1到S5是服务端,既代表Proposer又代表Acceptor。为了防止重复,Proposer提出的编号由两部分组成:

序列号.Server ID ----> 例如S1提出的提案编号,就是1.1、2.1、3.1……

 

这个过程表示,S1收到客户端的提案X,于是S1作为Proposer,给S1-S3发送Prepare(3.1)请求,由于Acceptor S1-S3没有接受过任何提案,所以接受该提案。然后Proposer S1-S3发送Accept(3.1, X)请求,提案X成功被接受。

在提案X被接受后,S5收到客户端的提案Y,S5给S3-S5发送Prepare(4.5)请求。对S3来说,4.5比3.1大,且已经接受了X,它会回复这个提案 (3.1, X)。S5收到S3-S5的回复后,使用X替换自己的Y,于是发送Accept(4.5, X)请求。S3-S5接受提案。最终所有Acceptor达成一致,都拥有相同的值X。

这种情况的结果是:新Proposer会使用已接受的提案。

情况2:提案未接受,新Proposer可见

 

S3接受了提案(3.1, X),但S1-S2还没有收到请求。此时S3-S5收到Prepare(4.5),S3会回复已经接受的提案(3.1, X),S5将提案值Y替换成X,发送Accept(4.5, X)给S3-S5,对S3来说,编号4.5大于3.1,所以会接受这个提案。

然后S1-S2接受Accept(3.1, X),最终所有Acceptor达成一致。

这种情况的结果是:新Proposer会使用已提交的值,两个提案都能成功。

情况3:提案未接受,新Proposer不可见

S1接受了提案(3.1, X),S3先收到Prepare(4.5),后收到Accept(3.1, X),由于3.1小于4.5,会直接拒绝这个提案。所以提案X无法收到超过半数的回复,这个提案就被阻止了。提案Y可以顺利通过。

这种情况的结果是:新Proposer使用自己的提案,旧提案被阻止。

五、总结

Paxos是分布式一致性问题中的重要共识算法。在Basic Paxos中,介绍了3种基本角色Proposer、Acceptor、Learner,以及提案时可能发生的3种基本情况。同时因为Paxos的提出者Leslie Lamport只是提出了一个思想,并没有给出工程的实现,也由于Paxos工程实现上的困难,许多算法基于Paxos思想创作出来并进行了改进并做出了工程上的实现,如Raft、ZAB等,这些算法留作以后再作介绍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值