awesome-fenix icon indicating copy to clipboard operation
awesome-fenix copied to clipboard

「Comment」https://icyfenix.cn/distribution/consensus/paxos.html

Open fenixsoft opened this issue 4 years ago • 18 comments

https://icyfenix.cn/distribution/consensus/paxos.html

fenixsoft avatar May 08 '20 08:05 fenixsoft

我承认我智商有问题

makerlee avatar Dec 15 '20 03:12 makerlee

“提案节点的Prepare请求中会附带一个全局唯一的数字n作为提案ID”,加上“递增”更为准确

UUNNFLY avatar Dec 18 '20 11:12 UUNNFLY

具体情况分析的情况一, “假设是S3,那么S3提供的Promise中必将包含S1已设定好的值X”,周大哥,应该是S3提供的Accept吧? 另外应答中返回的值是这样定义的"不违背以前作出的承诺的前提下,回复已经批准过的提案中ID最大的那个提案所设定的值和提案ID,如果该值从来没有被任何提案设定过,则返回空值。",情况一S3的提案是不是首次设置值?是的话,S3收到的Accept中的值是不是应该是null?如果不是首次设置值,是不是批准过最大提案ID对应的值呢,而不是返回S3本次提案的值X?

dengchaoh avatar Dec 21 '20 13:12 dengchaoh

@dengchaoh

具体情况分析的情况一, “假设是S3,那么S3提供的Promise中必将包含S1已设定好的值X”,周大哥,应该是S3提供的Accept吧? 另外应答中返回的值是这样定义的"不违背以前作出的承诺的前提下,回复已经批准过的提案中ID最大的那个提案所设定的值和提案ID,如果该值从来没有被任何提案设定过,则返回空值。",情况一S3的提案是不是首次设置值?是的话,S3收到的Accept中的值是不是应该是null?如果不是首次设置值,是不是批准过最大提案ID对应的值呢,而不是返回S3本次提案的值X?

是Promise。
按照场景假设,S5是提案节点,S3是决策节点,提案节点会发出Prepare和Accept请求,决策节点会响应Promise和Accepted应答。可见S3是不可能发出Accept消息的。

只关注S1、S3、S5的之间的交互,此场景的时间线顺序如下:

  1. S1向S3提交Prepare(3.5)的请求
  2. S3向S1返回Promise(3.5,null)的响应
  3. S1收到Promise(3.5,null)后,提交Accept(3.5,X)的请求
  4. S3收到Accept(3.5,X)后,向S5返回Accepted(3.5,X)的响应
  5. S5向S3提交Prepare(4.5)的请求
  6. S3收到后发现已有设置值X,向S5返回Promise(4.5,X)的响应
  7. S5收到Promise(4.5,X)后,无条件接受X代替原本的Y作为自己的提案值,提交Accept(4.5,X)的请求
  8. S3收到Accept(4.5,X)后,向S5返回Accepted(4.5,X)的响应

fenixsoft avatar Dec 22 '20 02:12 fenixsoft

@fenixsoft @dengchaoh

具体情况分析的情况一, “假设是S3,那么S3提供的Promise中必将包含S1已设定好的值X”,周大哥,应该是S3提供的Accept吧? 另外应答中返回的值是这样定义的"不违背以前作出的承诺的前提下,回复已经批准过的提案中ID最大的那个提案所设定的值和提案ID,如果该值从来没有被任何提案设定过,则返回空值。",情况一S3的提案是不是首次设置值?是的话,S3收到的Accept中的值是不是应该是null?如果不是首次设置值,是不是批准过最大提案ID对应的值呢,而不是返回S3本次提案的值X?

是Promise。
按照场景假设,S5是提案节点,S3是决策节点,提案节点会发出Prepare和Accept请求,决策节点会响应Promise和Accepted应答。可见S3是不可能发出Accept消息的。

只关注S1、S3、S5的之间的交互,此场景的时间线顺序如下:

  1. S1向S3提交Prepare(3.5)的请求
  2. S3向S1返回Promise(3.5,null)的响应
  3. S1收到Promise(3.5,null)后,提交Accept(3.5,X)的请求
  4. S3收到Accept(3.5,X)后,向S5返回Accepted(3.5,X)的响应
  5. S5向S3提交Prepare(4.5)的请求
  6. S3收到后发现已有设置值X,向S5返回Promise(4.5,X)的响应
  7. S5收到Promise(4.5,X)后,无条件接受X代替原本的Y作为自己的提案值,提交Accept(4.5,X)的请求
  8. S3收到Accept(4.5,X)后,向S5返回Accepted(4.5,X)的响应

明白了。之前对Promise应答有误解,以为它只做了两个承诺的事情,其实它也做出了一个应答;对ACCEPT也有误解,以为是决策节点提供两个承诺后,随机主动发出的应答。正确的是Promise做到了两个承诺一个应答的事情。提案节点收到Promise后,再次发起一个Accept请求,决策节点再给出Accepted应答。 因为提案节点收到Promise应答以后,还要再次发送一个Accept请求来得到批准,这中间如果插入更大ID的提案请求,Accept请求可能失败,产生情况三、四发生的可能性。串起来了。 感谢周大哥,给出的时间线顺序非常有帮助。

dengchaoh avatar Dec 22 '20 02:12 dengchaoh

情况二中有一句“譬如图6-3所示,S5发起提案的Prepare请求时,X并未获得多数派批准,但由于S3已经批准的关系,最终共识的结果仍然是X。”,这么说来,值一旦设定,就不能修改了吗?

bigbenfather avatar Feb 25 '21 02:02 bigbenfather

@bigbenfather 情况二中有一句“譬如图6-3所示,S5发起提案的Prepare请求时,X并未获得多数派批准,但由于S3已经批准的关系,最终共识的结果仍然是X。”,这么说来,值一旦设定,就不能修改了吗?

文中有写:

值一旦设置成功,就是不会丢失也不可变的。请注意,Paxos是典型的基于操作转移模型而非状态转移模型来设计的算法,这里的“设置值”不要类比成程序中变量赋值操作,应该类比成日志记录操作

fenixsoft avatar Feb 25 '21 03:02 fenixsoft

https://www.youtube.com/watch?v=BhosKsE8up8 可以结合这个视频看看,会更好理解

niceczj avatar Jul 01 '21 07:07 niceczj

看了这篇文章后清晰了挺多,感谢作者。 不过有个问题没太弄明白,算法的一个前提是

如果提案节点发现响应的决策节点中,已经有至少一个节点的应答中包含有值了,那它就不能够随意取值了,必须无条件地从应答中找出提案 ID 最大的那个值并接受

不明白为什么要有这种前提。 有了这个前提,一个值设置完成后,不是无法改变了吗?后面prepare对应的promise不都会返回有值吗?还希望能帮忙解答下疑惑

robot88 avatar Jul 02 '21 03:07 robot88

@robot88 看了这篇文章后清晰了挺多,感谢作者。 不过有个问题没太弄明白,算法的一个前提是

如果提案节点发现响应的决策节点中,已经有至少一个节点的应答中包含有值了,那它就不能够随意取值了,必须无条件地从应答中找出提案 ID 最大的那个值并接受

不明白为什么要有这种前提。 有了这个前提,一个值设置完成后,不是无法改变了吗?后面prepare对应的promise不都会返回有值吗?还希望能帮忙解答下疑惑

prepare只是准备阶段,还没就value值达成一致,真正执行更新value值 是“形成决议,供记录节点学习”这个阶段执行的。

AnyUncle avatar Dec 06 '21 13:12 AnyUncle

@fenixsoft @dengchaoh

具体情况分析的情况一, “假设是S3,那么S3提供的Promise中必将包含S1已设定好的值X”,周大哥,应该是S3提供的Accept吧? 另外应答中返回的值是这样定义的"不违背以前作出的承诺的前提下,回复已经批准过的提案中ID最大的那个提案所设定的值和提案ID,如果该值从来没有被任何提案设定过,则返回空值。",情况一S3的提案是不是首次设置值?是的话,S3收到的Accept中的值是不是应该是null?如果不是首次设置值,是不是批准过最大提案ID对应的值呢,而不是返回S3本次提案的值X?

是Promise。
按照场景假设,S5是提案节点,S3是决策节点,提案节点会发出Prepare和Accept请求,决策节点会响应Promise和Accepted应答。可见S3是不可能发出Accept消息的。

只关注S1、S3、S5的之间的交互,此场景的时间线顺序如下:

  1. S1向S3提交Prepare(3.5)的请求
  2. S3向S1返回Promise(3.5,null)的响应
  3. S1收到Promise(3.5,null)后,提交Accept(3.5,X)的请求
  4. S3收到Accept(3.5,X)后,向S5返回Accepted(3.5,X)的响应
  5. S5向S3提交Prepare(4.5)的请求
  6. S3收到后发现已有设置值X,向S5返回Promise(4.5,X)的响应
  7. S5收到Promise(4.5,X)后,无条件接受X代替原本的Y作为自己的提案值,提交Accept(4.5,X)的请求
  8. S3收到Accept(4.5,X)后,向S5返回Accepted(4.5,X)的响应
  1. S3收到Accept(3.5,X)后,向S5返回Accepted(3.5,X)的响应

S5应该是S1吧

  1. S3收到Accept(3.5,X)后,向S1返回Accepted(3.5,X)的响应

AnyUncle avatar Dec 06 '21 13:12 AnyUncle

"Basic Paxos 只能对单个值形成决议" 建议把这句话放在前面,更好理解,不然在阅读的过程中一直再想,要是另一个变量也需要投票,怎么区分呢?阅读过程中到网上找了各种材料才发现,这个算法它压根只能对一个变量进行选举。最后感谢作者的杰作。

Neway13 avatar Dec 11 '21 09:12 Neway13

@robot88 看了这篇文章后清晰了挺多,感谢作者。 不过有个问题没太弄明白,算法的一个前提是

如果提案节点发现响应的决策节点中,已经有至少一个节点的应答中包含有值了,那它就不能够随意取值了,必须无条件地从应答中找出提案 ID 最大的那个值并接受

不明白为什么要有这种前提。 有了这个前提,一个值设置完成后,不是无法改变了吗?后面prepare对应的promise不都会返回有值吗?还希望能帮忙解答下疑惑

每个instance中选择一个value,多个instance组成状态机。达成共识后确实是不允许改变的啊。

childishwanghe avatar Jan 04 '22 09:01 childishwanghe

情况四,S5的提案不应该是 P4.5吗,求大佬解惑

dongzhi0312 avatar Apr 02 '22 08:04 dongzhi0312

@dongzhi0312 情况四,S5的提案不应该是 P4.5吗,求大佬解惑

算法只要求后来的 ID 比之前的大即可,不要求具体的数值。

比如,情况四,S1 的提案是 3.1,S5 的提案可以是 3.5 (3.5 > 3.1) 也可以是 4.5 (4.5 > 3.1) 或者是 5.5 (5.5 > 3.1)。

个人猜测,具体实现中,这个递增的 ID 可能用的是 timestamp 去做的。

prchann avatar Apr 27 '22 03:04 prchann

强一致(不一致的情况不对外界暴露)

Paxos:

  1. 阶段
    1. Prepare - 占坑
      1. 已 accept 其他提案:返回已 accept 的值
      2. 已 prepare 比当前ID大的提案:沉默(不响应)
      3. 否则:返回 (提案ID, null)
    2. Accept - 拉屎
      1. 已 accept 比当前ID大的提案:沉默
      2. 已 prepare 比当前ID大的提案:沉默
      3. 否则:accept 当前提案的值
  2. 特点
    1. Prepare 过半成功:表明还没有其他提案已过半 accept,当前提案还有机会超越
    2. 允许竞争
    3. 可用性也会随节点增加而降低,只是降低速度没那么快 O(N/2);2PC 是 O(N)
    4. :question: 分出胜负前,若节点 A 已确认了小 ID 的值(但最终结果来自大 ID),此时读值会怎样?

prchann avatar Apr 27 '22 14:04 prchann

@AnyUncle

@fenixsoft @dengchaoh

具体情况分析的情况一, “假设是S3,那么S3提供的Promise中必将包含S1已设定好的值X”,周大哥,应该是S3提供的Accept吧? 另外应答中返回的值是这样定义的"不违背以前作出的承诺的前提下,回复已经批准过的提案中ID最大的那个提案所设定的值和提案ID,如果该值从来没有被任何提案设定过,则返回空值。",情况一S3的提案是不是首次设置值?是的话,S3收到的Accept中的值是不是应该是null?如果不是首次设置值,是不是批准过最大提案ID对应的值呢,而不是返回S3本次提案的值X?

是Promise。
按照场景假设,S5是提案节点,S3是决策节点,提案节点会发出Prepare和Accept请求,决策节点会响应Promise和Accepted应答。可见S3是不可能发出Accept消息的。

只关注S1、S3、S5的之间的交互,此场景的时间线顺序如下:

  1. S1向S3提交Prepare(3.5)的请求
  2. S3向S1返回Promise(3.5,null)的响应
  3. S1收到Promise(3.5,null)后,提交Accept(3.5,X)的请求
  4. S3收到Accept(3.5,X)后,向S5返回Accepted(3.5,X)的响应
  5. S5向S3提交Prepare(4.5)的请求
  6. S3收到后发现已有设置值X,向S5返回Promise(4.5,X)的响应
  7. S5收到Promise(4.5,X)后,无条件接受X代替原本的Y作为自己的提案值,提交Accept(4.5,X)的请求
  8. S3收到Accept(4.5,X)后,向S5返回Accepted(4.5,X)的响应
  1. S3收到Accept(3.5,X)后,向S5返回Accepted(3.5,X)的响应

S5应该是S1吧

  1. S3收到Accept(3.5,X)后,向S1返回Accepted(3.5,X)的响应

我也是这样想

@AnyUncle

@fenixsoft @dengchaoh

具体情况分析的情况一, “假设是S3,那么S3提供的Promise中必将包含S1已设定好的值X”,周大哥,应该是S3提供的Accept吧? 另外应答中返回的值是这样定义的"不违背以前作出的承诺的前提下,回复已经批准过的提案中ID最大的那个提案所设定的值和提案ID,如果该值从来没有被任何提案设定过,则返回空值。",情况一S3的提案是不是首次设置值?是的话,S3收到的Accept中的值是不是应该是null?如果不是首次设置值,是不是批准过最大提案ID对应的值呢,而不是返回S3本次提案的值X?

是Promise。
按照场景假设,S5是提案节点,S3是决策节点,提案节点会发出Prepare和Accept请求,决策节点会响应Promise和Accepted应答。可见S3是不可能发出Accept消息的。

只关注S1、S3、S5的之间的交互,此场景的时间线顺序如下:

  1. S1向S3提交Prepare(3.5)的请求
  2. S3向S1返回Promise(3.5,null)的响应
  3. S1收到Promise(3.5,null)后,提交Accept(3.5,X)的请求
  4. S3收到Accept(3.5,X)后,向S5返回Accepted(3.5,X)的响应
  5. S5向S3提交Prepare(4.5)的请求
  6. S3收到后发现已有设置值X,向S5返回Promise(4.5,X)的响应
  7. S5收到Promise(4.5,X)后,无条件接受X代替原本的Y作为自己的提案值,提交Accept(4.5,X)的请求
  8. S3收到Accept(4.5,X)后,向S5返回Accepted(4.5,X)的响应
  1. S3收到Accept(3.5,X)后,向S5返回Accepted(3.5,X)的响应

S5应该是S1吧

  1. S3收到Accept(3.5,X)后,向S1返回Accepted(3.5,X)的响应

我也是这样想

TG186 avatar Aug 07 '22 13:08 TG186

一脑子浆糊大概就是看完这篇文章的感觉

TANMIYOO avatar Nov 25 '22 02:11 TANMIYOO