分布式协议与算法实战
韩健
腾讯资深工程师
23193 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 31 讲
分布式协议与算法实战
15
15
1.0x
00:00/00:00
登录|注册

05 | Paxos算法(一):如何在多个节点间确定某变量的值?

提案编号
容错
二阶段提交
提案
容错能力
接受(Accept)阶段
准备(Prepare)阶段
三种角色的关系
学习者(Learner)
接受者(Acceptor)
提议者(Proposer)
课堂思考
相关概念
Multi-Paxos
Basic Paxos
Paxos算法

该思维导图由 AI 生成,仅供参考

你好,我是韩健。
提到分布式算法,就不得不提 Paxos 算法,在过去几十年里,它基本上是分布式共识的代名词,因为当前最常用的一批共识算法都是基于它改进的。比如,Fast Paxos 算法、Cheap Paxos 算法、Raft 算法等等。而很多同学都会在准确和系统理解 Paxos 算法上踩坑,比如,只知道它可以用来达成共识,但不知道它是如何达成共识的。
这其实侧面说明了 Paxos 算法有一定的难度,可分布式算法本身就很复杂,Paxos 算法自然也不会例外,当然了,除了这一点,还跟兰伯特有关。
兰伯特提出的 Paxos 算法包含 2 个部分:
一个是 Basic Paxos 算法,描述的是多节点之间如何就某个值(提案 Value)达成共识;
另一个是 Multi-Paxos 思想,描述的是执行多个 Basic Paxos 实例,就一系列值达成共识。
可因为兰伯特提到的 Multi-Paxos 思想,缺少代码实现的必要细节(比如怎么选举领导者),所以在理解上比较难。
为了让你理解 Paxos 算法,接下来我会用 2 节课的时间,分别以 Basic Paxos 和 Multi-Paxos 为核心,带你了解 Basic Paxos 如何达成共识,以及针对 Basic Paxos 的局限性 Multi-Paxos 又是如何改进的。今天咱们先来聊聊 Basic Paxos。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Paxos算法是分布式共识的核心算法之一,通过提议者、接受者和学习者三种角色的协作,实现多节点间确定某变量值的目标。文章以生动的比喻和实例,深入解析了Paxos算法的基本原理和核心概念,包括准备和接受两个阶段的共识协商过程。通过对Paxos算法的理解,读者可以更好地掌握分布式共识算法的核心内容,为设计自己的算法提供参考。文章还强调了Basic Paxos的容错能力,源自“大多数”的约定,使得共识协商在少于一半的节点出现故障时仍能正常工作。总之,本文深入浅出地介绍了Paxos算法的原理和特点,为读者提供了深入理解分布式共识算法的重要参考资料。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《分布式协议与算法实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(113)

  • 最新
  • 精选
  • 小晏子
    如果节点 A、B 已经通过了提案[5, 7],节点 C 未通过任何提案,那么当客户端 3 提案编号为 9 ,通过 Basic Paxos 执行“SET X = 6”, 最终节点值应该是[9,7], 过程如下: 1. 在准备阶段,节点C收到客户端3的准备请求[9,6], 因为节点C未收到任何提案,所以返回“尚无提案”的相应。这时如果节点C收到了之前客户端的准备请求[5, 7], 根据提案编号5小于它之前响应的准备请求的提案编号9,会丢弃该准备请求。 2. 客户端3发送准备请求[9,6]给节点A,B,这时因为节点A,B已经通过了提案[5,7], 根据“如果接受者之前有通过提案,那么接受者将承诺,会在准备请求的响应中,包含已经通过的最大编号的提案信息”,节点A,B会返回[5,7]给客户端3. 3. 客户端3发送会接受请求[9,7]给节点A,B,C(注意这里使用的是准备阶段的最大提议编号和已经被通过的值),因为此时请求编号9不小于之前的请求编号,所以所有节点接受该请求[9,7]. 4, 所有学习者会接受该提案,学习该值。

    作者回复: 加一颗星:)

    2020-02-21
    38
    116
  • EidLeung
    “作者回复: 大多数节点就某个值,达成共识后,值就不再变了,哪怕有新的提案,这个值,也能保证不再变了。”这个最后的值肯定是7,至于编号嘛,取最大的🤪。

    作者回复: 加一颗星:)

    2020-02-23
    5
    59
  • 竹马彦四郎的好朋友影法師
    这里总结一下韩老师讲解的为什么需要Basic paxos算法,或者说Basic Paxos 算法到底解决了个什么问题 Basic Paxos 算法解决的问题是一个分布式系统如何就某个值X(决议)达成一致。一个典型的场景是,在一个分布式数据库存储中,如果各节点的初始状态一致,每个节点执行相同的操作序列(例如上面是每个节点都要执行SET(X, 3)操作和SET(X, 7)操作,其中SET(X, 3)指令是客户端1向每个节点发出,SET(X, 7)指令是客户端2向每个节点发出),那么他们最后肯定能达到一个一致的状态。例如A、B、C三个节点执行的指令按照顺序都是 SET(X,3)-->SET(X, 7)的话,则A、B、C三个节点最终X的值都是7. 但是网络的不可靠性导致实际上最后每个节点执行的指令顺序并不一样,如果A节点、B节点执行顺序是SET(X,3)-->SET(X,7),则A、B节点上最后的值就是X=7,而C节点上可能因为网络原因执行的顺序是 SET(X,7)-->SET(X,3), 结果最后C节点上的X值就是3了. 这种情况可能导致客户端发送相同执行指令,但是最终节点上的值不完全相同. 我们当然不希望看到这种情况的发生. 于是 Basic paxos算法横空出世. basic paxos算法需要在每一条指令上执行一个“一致性算法”以保证每个节点看到的指令一致。

    作者回复: 加一颗星:)

    2020-05-01
    5
    29
  • Jialin
    如果节点 A、B 已经通过了提案[5, 7],节点 C 未通过任何提案,那么当客户端 3 提案编号为 9 时,通过 Basic Paxos 执行“SET X = 6”时 准备阶段:当节点 A、B 收到提案编号为 9 的准备请求的时候,因为提案编号 9 大于它们之前响应的准备请求的提案编号 5,但这两个节点之前通过了提案[5, 7],接受者A、B会在准备请求的响应中,包含已经通过的最大编号的提案信息[5, 7],并承诺以后不再响应提案编号小于等于 9 的准备请求,不会通过编号小于 9 的提案;由于之前没有通过任何提案,所以节点 C 将返回一个 “尚无提案”的响应。并承诺以后不再响应提案编号小于等于 9 的准备请求,不会通过编号小于 9 的提案。 接受阶段:当客户端 3 收到大多数的接受者的准备响应后(节点 A、B 和节点 C),根据响应中提案编号最大的提案的值,来设置接受请求中的值。因为来自节点 A、B 的准备响应中为[5, 7]和C的准确响应为空,所以就把节点 A、B的响应值 7 作为提案的值,发送接受请求[9, 7]。当节点 A、B、C 收到接受请求[9, 7]的时候,由于提案的提案编号 9 不小于三个节点承诺能通过的提案的最小提案编号 9,所以就通过提案[9, 7],也就是接受了值 7,三个节点就 X 值为 7 达成了共识

    作者回复: 加一颗星:)

    2020-02-21
    5
    29
  • vi
    看了评论的推导,理解了结果是[9,7],还有另外一个问题,对于接收阶段的值是如何确定的呢? 如果问题改为,只有一个节点A通过提案[5, 7],另外两个节点 B,C 未通过任何提案,这个时候客户端发起[9,6]的请求时,三个结点的最终值还会是[9,7]么?

    作者回复: 最终的值,可能是6,也可能是7,取决于节点A的准备响应,是否是“大多数”中的一个。

    2020-02-28
    13
    15
  • NICK
    对思考题有个疑问,这个x的值是不是只要大多数节点通过后就不能被update了?即只要过半数的节点通过后,无论后面的新的请求的提案编号多高,这个值都不会被更新了?这个感觉哪里不对啊!

    作者回复: 加一颗星:是这样的:),通过提案是不会改的的,如果有节点上不存在通过的提案,不管后来的提议者,如何提交提案,值都不变的,也就是节点C上的X值是7,3个节点上的X值,都是7。 通过这个思考题,希望大家注意到这么2点,首先在Basic Paxos的准备阶段,是会发现之前通过的提案的值;另外,Basic Paxos是一个共识算法,就一个值达成共识后,共识的这个值,就不会再变了。

    2020-02-29
    4
    14
  • 88591
    准备阶段: 1、 client3 [9,]—>A 、A 已提案通过,承诺编码为>=9、被返回 [5,7] 2、client3 [9,]—>B 、B 已提案通过,承诺编码为>=9、 被返回 [5,7] 3、client3 [9,]—>C 、C 无提案通过,承诺编码为>=9、 被返回尚无提案 C 收到的提议 [5,7]或者[9,6],不管是先收到5,还是9,都会承诺9. 接受阶段 client3 :依据A,B 返回的信息为[5,7],多数提议为【5,7】,只更新自己的编码不更新值 1、client3 [9,7]—> A ,A 提案通过。 2、client3 [9,7]—>B , B 提案通过, 3、client3 [9,7]—>C ,C 提案通过 4、学习者学习改提案值

    作者回复: 加一颗星:)

    2020-03-31
    2
    12
  • Dovelol
    老师好,今天题目开始说到是一个只读的kv存储,那是不是只要最后所有节点数据一样就算成功了?如果某个节点挂了,重启了该怎么获取到最新值呢?如果是可读写的节点,该怎么取更新某个值呢?

    作者回复: 大多数节点就某个值,达成共识后,值就不再变了,哪怕有新的提案,这个值,也能保证不再变了。节点挂了,属于系统实现层面,如何同步数据的问题,如果要处理的话,比如,可以这么做,实现数据同步机制或重新执行Basic Paxos。如果更新某个值,这是需要Multi-Paxos和状态机,我19、20讲,我会具体说说。 咱们要注意的一点,Basic Paxos只能就单值达成共识,属于一个基础算法,Multi-Paxos,才能在实际场景中落地。

    2020-02-22
    2
    12
  • piboye
    怎么保障提案号不重复呢?

    作者回复: 加一颗星:),可以通过独立单调递增、随机超时,来避免重复冲突,比如,可以参考Hashicorp Raft对CurrentTerm的实现。

    2020-04-27
    2
    11
  • byrne
    老师,我下面的例子是我哪里理解错了,望百忙中抽空回答下,谢谢! 假设有ABC三个节点,客户端甲发起一次提案编号1将X的值设为1,假设AB两个节点都收到客户端甲这次提案,客户端甲得到AB两个节点的应答之后开始进入第二阶段(三个节点中的两个,所以已经是大部分节点给了应答),假设此时客户端乙又发起一次提案编号2将X的值设为2,假设B和C两个节点收到客户端乙的提案,B发现编号2大于原先的编号1,因此给客户端乙回了没有提案,C由于从来没收到提案,因此也给客户端乙回了没有提案,此时客户端乙也进入了第二阶段,这样客户端甲将A节点的X设定为1,客户端乙将B和C节点的X设为2,这样两边就不一致了。

    作者回复: 加一颗星:),这种情况属于一个异常情况,与实现有关,也是Basic Paxos没有约定的,在实现中,客户端重试就可以了。其实,异常情况(比如网络连接失败)虽然会肯定发生,但概率低,持续时间很短,“失败 - 缓存 - 重试”是一种很好的解决办法。

    2020-05-20
    11
    8
收起评论
显示
设置
留言
99+
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部