算法分析Basic Paxos算法
Posted 区块链and语义研究实验室
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法分析Basic Paxos算法相关的知识,希望对你有一定的参考价值。
Paxos算法介绍
Paxos算法是Lamport于1990年提出的一种基于消息传递的一致性算法。Paxos 算法解决的问题是一个分布式系统如何就某个值(决议)达成一致。一个典型的场景是,在一个分布式数据库系统中,如果各节点的初始状态一致,每个节点都执行相同的操作序列,那么他们最后能得到一个一致的状态。为保证每个节点执行相同的命令序列,需要在每一条指令上执行一个“一致性算法”以保证每个节点看到的指令一致,是分布式计算中的重要问题。在过去很长一段时间,Paxos算法可以说是分布式共识的代名词,当前最常用的一批共识算法,比如,Fast Paxos算法,Cheap Paxos算法,比较有名的Raft算法也是基于它发展而来的。现实中,有很多基于Paxos的产品,比如Google的Chubby,Spanner,IBM的SVC等。
Paxos算法类型
Paxos本来是虚构故事中的一个小岛,议会通过表决来达成共识。但是议员可能离开,信使可能走丢,或者重复传递消息。对应到分布式系统的节点故障和网络故障。
如上图所示,假设议员要提议中午吃什么。如果有一个或者多个人同时提议,但一次只能通过一个提议,这就是Basic Paxos,是Paxos中最基础的协议。
什么是“角色”
Paxos有一个最重要的概念“角色”,Paxos有三个“角色”,提议者(Proposer)、接受者(Acceptor)和学习者(Learner)。其中,提议者和接受者是这里最重要的两个角色,Paxos最核心的就是定义他们之间的通讯规则来保证某个变量在分布式系统中的一致性。
提议者(Proposer)
提议者是提出议案的人,每个议案都有一个议案号,议案号是区别不同议案的唯一标识,而且议案号是有大小次序的。一般来说,集群中收到客户端请求的节点,才是提议者。
接受者(Acceptor)
对每个提议的值进行投票,并存储接收的值。通常来说,集群中的所有节点都扮演着接受者的角色,参与共识协商,并接收和存储数据。
所以,经常会发现集群中的节点其实可以身兼多个“角色”。如上图那样,假设集群中有3个节点,当1个节点收到了请求,那么该节点作为提议者发起了二阶段提交,然后这个节点可以和另外两个节点一起作为接受者进行共识协商。
学习者(Learner)
被告知投票的结果,接收达成的共识值,并存储保存。不参与投票的过程。通常,学习者是备份节点,就好比“Master-Slave”中的Slave,被动地接收数据,实现容灾备份。
对这三个角色的功能总结如下:
Paxos算法
Paxos算法分两个阶段完成,准备阶段(Prepare)和接受阶段(Accept)。
Proposer需要发出两次请求,Prepare请求和Accept请求。Acceptor根据其收集的信息,接受或者拒绝提案。
Prepare阶段
Proposer选择一个提案编号n,发送Prepare(n)请求给超过半数(或更多)的Acceptor。
Acceptor收到消息后,如果n比它之前见过的编号大,就回复这个消息,而且以后不会接受小于n的提案。另外,如果之前已经接受了小于n的提案,回复那个提案编号和内容给Proposer。
Accept阶段
当Proposer收到超过半数的回复时,就可以发送Accept(n, value)请求了。n就是自己的提案编号,value是Acceptor回复的最大提案编号对应的value,如果Acceptor没有回复任何提案,value就是Proposer自己的提案内容。
Acceptor收到消息后,如果n大于等于之前见过的最大编号,就记录这个提案编号和内容,回复请求表示接受。
当Proposer收到超过半数的回复时,说明自己的提案已经被接受。否则回到第一步重新发起提案。
完整算法如下图所示:
Acceptor需要持久化存储minProposal、acceptedProposal、acceptedValue这3个值。
算法分析
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使用自己的提案,旧提案被阻止。
活锁
活锁发生的几率很小,但是会严重影响性能。就是两个或者多个Proposer在Prepare阶段发生互相抢占的情形。
解决方案是Proposer失败之后给一个随机的等待时间,这样就减少同时请求的可能。
总结
Paxos算法是一种基于消息传递的一致性算法,近几年Paxos算法的普遍使用也证明它在分布式一致性算法中的重要地位,它除了实现了共识之外,还实现了容错,它不像其它常用的分布式事务算法那样,要所有节点都同意后才提交操作,而是只要少于一半节点出错集群也是能正常工作的。
区块链&语义研究实验室
以上是关于算法分析Basic Paxos算法的主要内容,如果未能解决你的问题,请参考以下文章