Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >分布式理论:深入浅出Paxos算法

分布式理论:深入浅出Paxos算法

作者头像
Java高级架构
发布于 2019-01-02 09:52:50
发布于 2019-01-02 09:52:50
9160
举报
文章被收录于专栏:JAVA高级架构JAVA高级架构

前言

Paxos算法是用来解决分布式系统中,如何就某个值达成一致的算法。它晦涩难懂的程度完全可以跟它的重要程度相匹敌。目前关于paxos算法的介绍已经非常多,但却很少有人能对P2c提出自己的见解,大多数是和稀泥式的人云亦云,但我觉着应该旗帜鲜明的亮出自己的观点,大家一起讨论,才能学到东西。希望我能将自己的观点表述清楚。

我个人认为理解Paxos有两个关键:

  1. 为什么要对提案进行顺序编号(或者说更大的编号意味着什么)。
  2. 为什么Promise能保证一致性(答案隐含在第1点中)

一致性问题

假设有一组服务器保存了用户的余额,初始是100块,现在用户提交了两个订单,一个订单是消费10元,一个订单是充值50元。由于网络错误和延迟等原因,导致一部分服务器只收到了第一个订单(余额更新为90元),一部分服务器只收到了第二个订单(余额更新为150元),还有一部分服务器两个订单都接收到了(余额更新为140元),这三者无法就最终余额达成一致。这就是一致性问题。

一致性算法并不保证所有提出的值都是正确的(这可能是安全管理员的职责)。我们假设所有提交的值都是正确的,算法需要负责的使对到底该选哪个值做出决策,并使决策的结果被所有参与者获悉。

在正式开始介绍Paxos所面临的难题前,为了表述方便,先提一下Paxos算法中的三个角色,后面会比较频繁的用到:

  1. Proposer:议案发起者。
  2. Acceptor:决策者,可以批准议案。
  3. Learner:最终决策的学习者。

我们虚拟一个一致性问题的场景:有一个用户小绿,现在要对他的姓氏信息进行修改,此时有多个不同的议案被提出,如何就最终的结果达成一致。

首先看一下下面这种最简单的情况:A1接受了Pa的议案“赵”,A2和A3接受了Pb的议案“钱”,那么最终小绿应该姓什么?

答案很简单:超过半数的的议案就是最终的选定值。小绿应该姓“钱”!在议案提交后,Pa和Pb只要查询一下小绿姓氏,很容易就能查到 “钱”的数量超过半数,因此Pb的议案将会返回“成功”,Pa的议案将会返回“失败”。

P0. 当集群中,超过半数的Acceptor接受了一个议案,那我们就可以说这个议案被选定了(Chosen)。

P0已经是一个完备的一致性算法,保证了P0也就解决了一致性问题。但是P0的实用性不佳,一个议案想被半数以上的Acceptor接受是一件极其困难的事情!

看下面这种情况:A1,A2,A3分别接受了“赵”,“钱”,“孙”,结果没有任何一个议案形成多数派,所有的议案都将返回“失败”。议案的数量越多,那议案被选定的概率就越低,这显然是没法容忍的。

要解决这个问题,必须允许一个Acceptor接受多个议案,后接受的议案可以覆盖掉之前接受的议案。

如下图所示, A1已经接受了“赵”,A2已经接受了“钱”,此时Pc提出了“孙”,并被A1,A2,A3接受,这样就解决了无法形成多数派的问题。

但现在又会面临下图中的新问题:A1,A2,A3已经接受了“赵”,此时我们认为“赵”是被选定的,但此时偏偏Pb和Pc不识时务,Pb向A2提出了“钱”,Pc向A3提出了“孙”。这样就从一致性状态,又回到了不一致的状态…这显然破坏了一致性。

Paxos就是在上述背景下产生的,Paxos要实现的目标的是:

  1. 一次选举必须要选定一个议案(不能出现所有议案都被拒绝的情况)
  2. 一次选举必须只选定一个议案(不能出现两个议案有不同的值,却都被选定的情况)

Paxos算法的推导

首先,Paxos算法的必须要能满足第一个条件:

P1:一个Acceptor必须接受它收到的第一个议案。

要满足这个条件实在太过简单了,方法略。。。

下面是我个人对这个条件的理解,为什么必须满足这个条件:

假设只有一个Acceptor,只有一个Proposer。如果Acceptor出于某些原因拒绝了Proposer的议案,那必然导致Paxos的目标T1无法达成。因此可以认为目标T1隐含了P1。

在开始P2的推导的前,为了区分不同议案,需要先对每个Proposer的议案进行编号,编号时必须保证每个议案的编号具有唯一性(不讨论实现方法),而且编号是不断增大的。

Paxos的目标T2隐含了P2:

P2:如果一个值为v的议案被选定了,那么被选定的更大编号的议案,它的值必须也是v。

P2很容易理解,除了其中的一个形容词“更大编号的”,这个形容词很扎眼,为什么只对更大编号的议案进行限制,更小的编号怎么办?

老头子给的解释很简单“By induction on proposal number”(如果不看论文后半部分,没人知道他在说什么…)我说一下我自己的理解:

首先把“更大编号的”几个字换成“其他的”,我们称它为P2S。那么P2S能否满足Paxos的目标?答案是肯定的。然后比较P2和P2S,谁的约束更强?这得看“更小的编号”是怎么处理的,从论文后面的推演来看更小编号的议案绝对不允许被选定!!!因此满足P2的议案是P2S的一个子集。

显而易见,P2S和P2都能满足Paxos目标。换句话说,能满足Paxos目标的办法很多,但我们只选其中一个办法就OK了。不过,要选最简单的办法(看完后面就知道了)。

总之,现在我们可以得出一个结论:

如果P1和P2都能够被满足,那么Paxos的两个目标就能够达成。

如果你对上面这个结论没有异议,那么就说明你已经充分理解了P1和P2。

接下来就需要想办法,如何才能满足P2:议案在选定前,都要先被Acceptor接受,因此要满足P2,我们只要满足下面的条件:

P2a:如果一个值为v的议案被选定了,那么Acceptor接受的更大编号的议案,它的值必须也是v。

P2a是P2的充分条件,但是P2a存在一个大麻烦:当一个议案被选定后,一部分Acceptor无法立刻获得通知。例如下图中A1和A2已经接受了“赵”,这时“赵”就被选定了,此时Pb向A3提出了一个议案“钱”,这是A3接受的第一个议案,为了满足P1,A3必须接受这个议案,此时就会导致P2a无法被满足了。

为了解决上述的问题,我们想一下:要是此时不让Pb提出“钱”这个议案,而是提出“赵”这议案就万事大吉了。顺着这个思路,我们得到了P2b:

P2b:如果一个值为v的议案被选定了,那么Proposer提出的更大编号的议案,它的值必须也是v。

P2b是一个比P2a更强的约束,也就是说P2b是P2a的充分条件,只要能满足P2b,那P2a就自动满足。但P2b很难被满足,考虑下图这种情况,A1接受了议案“赵”,A2即将接受议案“赵”,此时Pb提出了一个议案“钱”,这种情况下我们又会遇到跟P2a完全相同的麻烦。

很明显,要想满足P2b,我们必需让Proposer拥有“预测未来”的能力,这听起来像在讲鬼故事,后面会想办法解决这一点。

在介绍如何“预测未来”之前,我们必须先确定Proposer在提出一个议案时,它的值该如何选取,因为取值的方法决定了“预测”的方法。

一个理所当然的取值方法:找到一个Acceptor的多数派集合,集合内被接受的议案的值都是v,此时Proposer提出一个新的议案,议案的值必须也是v;如果没有这样的多数派集合,那Proposer就任意提。

这个取值方法,完全能符合P2b,这是一目了然的,但问题出在 “预测”上,我们必须能预测到即将形成多数派的那个议案,如果有谁能做到那就真的是在讲鬼故事了。

Proposal提出议案的正确姿势:

P2c:在所有Acceptor中,任意选取半数以上的Acceptor集合,我们称这个集合为S。Proposal新提出的议案(简称Pnew)必须符合下面两个条件之一:

  1. 如果S中所有Acceptor都没有接受过议案的话,那么Pnew的编号保证唯一性和递增即可,Pnew的值可以是任意值。
  2. 如果S中有一个或多个Acceptor曾经接受过议案的话,要先找出其中编号最大的那个议案,假设它的编号为N,值为V。那么Pnew的编号必须大于N,Pnew的值必须等于V。

P2c提出议案的规则有点复杂,它真的能满足P2b吗?至少看上去不是那么一目了然…..老头子用了归纳法来证明P2c能满足P2b,但效果不佳,没什么人能看懂,所以下面的证明过程即使你看不懂也必要太沮丧(后面会给出图文解释)。

证明题(注意!前方高能):

已知议案

是集合中第一个被选定的议案,接受这个议案的Acceptor集合为

,在满足P2c的规则2的情况下,提出了一个新的议案

,n>m,证明

第一步,证明初始成立:当议案的编号n = m+1时,证明

因为

是第一个被选定的议案,因此在m+1提出之前,m必然是集群当中编号最大的议案。

根据P2c的规则2,议案

能够被提出,是因为存在一个多数派集合

,这个集合中,编号最大的议案的值为

。因为

都是多数派集合,所以他们必定存在交集。交集中的Acceptor必定都接受了

。m是整个集群最大的编号,当然也就是

中最大的编号,根据P2c的规则2,

必定等于

第二步,当n > m+1时,假设编号从m+1到n-1的议案的值都是

,证明

编号为m+1到n-1的议案提出后,我们没办法判断究竟那一个议案会被选定,但有一点是可以肯定的:所有接受了

的Acceptor构成了一个新的集合

,这个集合包含了集合

中的所有Acceptor,

显然是一个多数派集合,这个集合接受的议案的编号在m到n-1之间,而且值为

。没有包含在集合

中的Acceptor所接受的议案一定小于m。

根据P2c的规则2,议案

能够被提出,那么一定存在一个多数派集合

,因为

都是多数派集合,所以他们必定存在交集。交集中的议案的最大编号一定大于等于m,小于等于n-1。因此集合

中编号最大的议案一定位于交集内。根据P2c的规则,

必定等于

这个证明过程,如果你能看懂,请受我三跪。。。

接下来,上图,举例说明。

假设有一个议案(3,Va)提交后,这个议案成为了被Acceptor集群选定的第一个议案 ,那此时集群的状态可能会如下图所示:

一共5个Acceptor,有3个Acceptor接受了议案(3,Va),刚刚过半。此时有一个编号为4的议案要提出,根据P2c的规则2,首先选一个过半的集合,就选上图中蓝色线圈出来的A3,A4,A5好了(任意选),这个集合中编号最大的议案是(3,Va),因此新提出的议案必定为(4,Va)。符合P2b。

议案(4,Va)提出后,集群的状态可能是下面这样:

此时再提出编号为5或6,7,8,9,10的议案,这个议案的值必定也是Va(不信的话请举出反例),符合P2b。依此类推。。。

由此可证,P2c是能够满足P2b的!!!

想想看P2,P2a,P2b中为什么一定要有“更大编号的”这几个扎眼的字眼,此时你应该能有一点感觉了,可能你会把它理解成“后提出的”,如果你是这样理解的话,请往下看。

有些童鞋肯定早就已经想到了:当议案(3,Va)提交后,这个议案成为了被Acceptor集群选定的第一个议案,此时集群的状态有没有可能是下面这样?

注意,这时议案(4,Vb)才是集群当中的编号最大的议案,要是这样就糟糕了!当我们提出编号为5的议案时,它的取值就有可能是Vb,导致无法满足P2b。

为了保证不出现这种情况,就要用到前面提到的“预测未来”的能力。跟P2c的议案规则相配套的,需要预测的未来是:

当一个议案在提出时(即使已经在发送的半路上了),它必须能够知道当前已经提出的议案的最大编号。

这样的话,议案(3,Va)提交时,就会知道有一个(4,Vb)的议案已经提交了,然后将自己的编号改成5或更大编号提交,一切就完美了。

但是你知道的,我们并不可能真的预测未来,换个思路,议案肯定是要提交给Acceptor的,只要由Acceptor来保证议案编号的顺序就OK了。于是有:

议案(n,v)在提出前,必须将自己的编号通知给半数以上的Acceptor,收到通知的Acceptor将n跟自己之前收到的通知进行比较,如果n更大,就将n确认为最大编号,当半数以上Acceptor确认n为最大编号时,议案(n,v)才能正式提交。

两个编号不同的议案,不可能同时被确认为最大编号,证明略。

但是实际环境上,上面的条件还不足以保证议案被接受的顺序,比如议案(n,Va)被确认为最大编号后,开始向Acceptor发送,此时(n+1,Vb)提出,由于网络速度的原因,(n+1,Vb)可能比(n,Va)更早被Acceptor接收到。

因此Acceptor收到一个新的编号n,在确认n比自己之前收到的编号大时,必须做出承诺(Promise):不再接受比n小的议案。

这个承诺会导致部分漏网之鱼(在发送途中被抢走最大编号的议案),无法形成多数派。

例如下图所示:有一个在途的议案(1,Va),当A2和A3对议案(2,Vb)做出承诺的同时,(1,Va)就失去了形成多数派的权利。

至此,我们就形成了一个完整的算法(具体实现请自行搜索PhxPaxos)。

后记

算法原文中,将Promise看做是P2c的具体实现,而我们将Promise看成是弥补P2c的补充条件。这两者没有质的差别,只是角度不同,我个人认为后一种更容易被理解,所以采用了后一种。不过采用后一种会遇到下面的麻烦:

按下面的顺序提交议案:

  • 议案(1,Va)向A1发送Prepare,获得A1的承诺。
  • 议案(2,Vb)向A1发送Prepare,获得A1的承诺。
  • 发送议案(1,Va)

此时A1会拒绝议案(1,Va)

采用后一种解释的话,会发现A1拒绝议案(1,Va)是违反了P1的,而采用前一种解释则不违反P1。(这不过是个文字游戏,我已经懒的去思考了,就这样吧)

如果我们将半数以上的Acceptor对同一个议案(n,v)做出承诺的状态称作是“锁定”状态。那么这个“锁定”状态具有以下性质:

排它性:所有比n小的议案都不允许提交,已经在途的议案,则不允许其形成多数派。

唯一性:任意时刻,全局只有一个议案能获得“锁定”状态。

原子性:议案n从锁定状态变为非锁定状态的过程是原子的,议案n+1从非锁定状态变更为锁定状态的过程也是原子的。

我相信(有点虚…),正是上面的这三条性质保证了一致性。

最后,感谢老头子给出的如此精彩的算法。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-12-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JAVA高级架构 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
paxos如此简单?
Google Chubby的作者Mike Burrows说过这个世界上只有一种一致性算法,那就是Paxos,其他算法都是残次品。
lainzhang
2022/08/24
7710
图解分布式一致性协议 Paxos 算法【BAT 面试题宝库附详尽答案解析】
https://en.wikipedia.org/wiki/Paxos_(computer_science)
一个会写诗的程序员
2019/12/20
1.4K0
图解分布式一致性协议 Paxos 算法【BAT 面试题宝库附详尽答案解析】
微信PaxosStore:深入浅出Paxos算法协议
“与其预测未来,不如限制未来”,这应该是Paxos协议的核心思想。Paxos协议本身是比较简单的,如何将Paxos协议工程化,才是真正的难题。这是来自微信工程师的经验,以供参考。
用户8964349
2021/09/06
9110
云计算核心算法(一)
  云计算的基础技术是集群技术,支撑集群高效协同工作需要一系列资源和任务调度算法,良好的调度算法可以提高集群处理能力,有效分配资源,加速作业进度。
Francek Chen
2025/01/23
1060
云计算核心算法(一)
分布式系统理论基础4:Paxos
本文转自:https://www.cnblogs.com/bangerlee/p/5655754.html
Java技术江湖
2019/12/03
5310
从Paxos到Raft,分布式一致性算法解析
导语 | 后台服务架构经过了集中式、SOA、微服务和服务网格四个阶段,目前互联网界大都使用微服务和服务网格。服务从集中式、中心化向分布式、去中心化不断演进,服务也变得更灵活,能够自动扩缩容、快速版本迭代等。但是分布式架构也将集中式下一些问题放大,比如通信故障、请求三态(成功、失败、超时)、节点故障等,这些问题会导致一系例数据不一致的问题,也是计算机领域的老大难问题。本文将与大家一起学习分布式一致性算法,因作者水平有限,若文中有不正处,还请多多指导。文章作者:董友康,腾讯PCG研发工程师。 一、CA
腾讯云开发者
2021/03/01
5320
一致性协议算法-2PC、3PC、Paxos、Raft、ZAB、NWR超详细解析
在常见的分布式系统中,总会发生诸如机器宕机或网络异常(包括消息的延迟、丢失、重复、乱序,还有网络分区)等情况。
王知无-import_bigdata
2020/12/18
3.5K0
一致性协议算法-2PC、3PC、Paxos、Raft、ZAB、NWR超详细解析
Paxos算法详解
Paxos、Raft分布式一致性算法应用场景一文讲述了分布式一致性问题与分布式一致性算法的典型应用场景。作为分布式一致性代名词的Paxos算法号称是最难理解的算法。本文试图用通俗易懂的语言讲述Paxos算法。
全栈程序员站长
2022/11/18
1.8K0
Paxos算法详解
Paxos 算法-浅显易懂的方式解析
在该一致性算法中有三种参与角色。分别为 “提议者(Proposer 向 “接受者” 提出提案)”、“接受者(Acceptor 收到 “提议者” 的提议后,向提议者表达自己的意见)”、“学习者(Learner 天被确定后,学习者获取被确定的提议)”
码哥字节
2021/07/27
3170
5分钟学分布式系统理论,从放弃到入门
随承载用户数量的增加和容灾的需要,越来越多互联网后台系统从单机模式切换到分布式集群。回顾自己毕业五年来的工作内容,同样有这样的转变。
Bug开发工程师
2020/03/31
6940
5分钟学分布式系统理论,从放弃到入门
聊聊 分布式一致性算法协议 Paxos
Google的粗粒度锁服务Chubby的设计开发者Burrows曾经说过:所有一致性协议本质上要么是Paxos要么是其变体。
码猿技术专栏
2023/05/01
1.1K0
聊聊 分布式一致性算法协议 Paxos
腾讯云后端15连问!
大家好,我是捡田螺的小男孩,最近一位朋友(6年工作经验)面了腾讯云,以下是面试题和答案。加油,一起卷。
捡田螺的小男孩
2022/04/06
2K0
腾讯云后端15连问!
分布式一致性算法-关于Paxos算法的理解
Paxos算法是一种一致性算法,用于在一个分布式多节点系统中确定一个确认的值,这个值可以是一条日志,可以是选举领导者,也可以是自己定义的任意数据。
相思不扫积久弥厚
2023/10/26
1930
Paxos 算法 :消息传递一致性
维基的简介:Paxos算法是莱斯利·兰伯特(Leslie Lamport,就是 LaTeX 中的"La",此人现在在微软研究院)于1990年提出的一种基于消息传递且具有高度容错特性的一致性算法。
西湖醋鱼
2020/12/30
3870
Paxos 算法 :消息传递一致性
分布式理论
随着计算机科学和互联网的发展,分布式场景变得越来越常见,能否处理好分布式场景下的问题,成为衡量一个工程师是否合格的标准。本文我们介绍下分布式系统相关的理论知识,这些理论是我们理解和处理分布式问题的基础。
一行舟
2022/08/25
4720
分布式理论
分布式最强算法之Paxos透析
上一篇:《分布式数据一致性模型有哪些?》 提到了Base理论提到了一个重要的点就是「最终一致性」 有什么方式能实现这种一致性呢?
斯文的程序
2020/04/24
1.6K0
分布式最强算法之Paxos透析
第一次这么通俗易懂的讲Paxos算法
大家对Paxos的看法基本是“晦涩难懂”,虽然论文和网上文章也很多,但总觉得“云山雾罩”,也不知道其具体原理以及到底能解决什么问题。
chengcheng222e
2021/11/04
4.1K1
搞懂分布式技术2:分布式一致性协议与Paxos,Raft算法
该系列博文会告诉你什么是分布式系统,这对后端工程师来说是很重要的一门学问,我们会逐步了解常见的分布式技术、以及一些较为常见的分布式系统概念,同时也需要进一步了解zookeeper、分布式事务、分布式锁、负载均衡等技术,以便让你更完整地了解分布式技术的具体实战方法,为真正应用分布式技术做好准备。
Java技术江湖
2019/12/02
6950
Paxos——分布式一致性算法
Paxos算法问世已经有将近30年的历史了,是目前公认最有效的解决分布式场景下一致性问题的算法之一,但是缺点是比较难懂,工程化比较难。本文希望能够辅以图例和通俗易懂的实例把Paxos算法讲清楚。
用户5546570
2019/06/06
1.3K0
Paxos——分布式一致性算法
分布式|Paxos和Raft复习
保持服务的持续可用,是核心业务对底层数据存储系统的要求。常见的1主N备的方案问题是“最大可用(Maximum Availability)”和“最大保护(Maximum Protection)”模式间抉择:
heidsoft
2021/03/15
6080
分布式|Paxos和Raft复习
相关推荐
paxos如此简单?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档