awesome-fenix
awesome-fenix copied to clipboard
「Comment」https://icyfenix.cn/distribution/consensus/paxos.html
https://icyfenix.cn/distribution/consensus/paxos.html
我承认我智商有问题
“提案节点的Prepare请求中会附带一个全局唯一的数字n作为提案ID”,加上“递增”更为准确
具体情况分析的情况一, “假设是S3,那么S3提供的Promise中必将包含S1已设定好的值X”,周大哥,应该是S3提供的Accept吧? 另外应答中返回的值是这样定义的"不违背以前作出的承诺的前提下,回复已经批准过的提案中ID最大的那个提案所设定的值和提案ID,如果该值从来没有被任何提案设定过,则返回空值。",情况一S3的提案是不是首次设置值?是的话,S3收到的Accept中的值是不是应该是null?如果不是首次设置值,是不是批准过最大提案ID对应的值呢,而不是返回S3本次提案的值X?
@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的之间的交互,此场景的时间线顺序如下:
- S1向S3提交Prepare(3.5)的请求
- S3向S1返回Promise(3.5,null)的响应
- S1收到Promise(3.5,null)后,提交Accept(3.5,X)的请求
- S3收到Accept(3.5,X)后,向S5返回Accepted(3.5,X)的响应
- S5向S3提交Prepare(4.5)的请求
- S3收到后发现已有设置值X,向S5返回Promise(4.5,X)的响应
- S5收到Promise(4.5,X)后,无条件接受X代替原本的Y作为自己的提案值,提交Accept(4.5,X)的请求
- S3收到Accept(4.5,X)后,向S5返回Accepted(4.5,X)的响应
@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的之间的交互,此场景的时间线顺序如下:
- S1向S3提交Prepare(3.5)的请求
- S3向S1返回Promise(3.5,null)的响应
- S1收到Promise(3.5,null)后,提交Accept(3.5,X)的请求
- S3收到Accept(3.5,X)后,向S5返回Accepted(3.5,X)的响应
- S5向S3提交Prepare(4.5)的请求
- S3收到后发现已有设置值X,向S5返回Promise(4.5,X)的响应
- S5收到Promise(4.5,X)后,无条件接受X代替原本的Y作为自己的提案值,提交Accept(4.5,X)的请求
- S3收到Accept(4.5,X)后,向S5返回Accepted(4.5,X)的响应
明白了。之前对Promise应答有误解,以为它只做了两个承诺的事情,其实它也做出了一个应答;对ACCEPT也有误解,以为是决策节点提供两个承诺后,随机主动发出的应答。正确的是Promise做到了两个承诺一个应答的事情。提案节点收到Promise后,再次发起一个Accept请求,决策节点再给出Accepted应答。 因为提案节点收到Promise应答以后,还要再次发送一个Accept请求来得到批准,这中间如果插入更大ID的提案请求,Accept请求可能失败,产生情况三、四发生的可能性。串起来了。 感谢周大哥,给出的时间线顺序非常有帮助。
情况二中有一句“譬如图6-3所示,S5发起提案的Prepare请求时,X并未获得多数派批准,但由于S3已经批准的关系,最终共识的结果仍然是X。”,这么说来,值一旦设定,就不能修改了吗?
@bigbenfather 情况二中有一句“譬如图6-3所示,S5发起提案的Prepare请求时,X并未获得多数派批准,但由于S3已经批准的关系,最终共识的结果仍然是X。”,这么说来,值一旦设定,就不能修改了吗?
文中有写:
值一旦设置成功,就是不会丢失也不可变的。请注意,Paxos是典型的基于操作转移模型而非状态转移模型来设计的算法,这里的“设置值”不要类比成程序中变量赋值操作,应该类比成日志记录操作
https://www.youtube.com/watch?v=BhosKsE8up8 可以结合这个视频看看,会更好理解
看了这篇文章后清晰了挺多,感谢作者。 不过有个问题没太弄明白,算法的一个前提是
如果提案节点发现响应的决策节点中,已经有至少一个节点的应答中包含有值了,那它就不能够随意取值了,必须无条件地从应答中找出提案 ID 最大的那个值并接受
不明白为什么要有这种前提。 有了这个前提,一个值设置完成后,不是无法改变了吗?后面prepare对应的promise不都会返回有值吗?还希望能帮忙解答下疑惑
@robot88 看了这篇文章后清晰了挺多,感谢作者。 不过有个问题没太弄明白,算法的一个前提是
如果提案节点发现响应的决策节点中,已经有至少一个节点的应答中包含有值了,那它就不能够随意取值了,必须无条件地从应答中找出提案 ID 最大的那个值并接受
不明白为什么要有这种前提。 有了这个前提,一个值设置完成后,不是无法改变了吗?后面prepare对应的promise不都会返回有值吗?还希望能帮忙解答下疑惑
prepare只是准备阶段,还没就value值达成一致,真正执行更新value值 是“形成决议,供记录节点学习”这个阶段执行的。
@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的之间的交互,此场景的时间线顺序如下:
- S1向S3提交Prepare(3.5)的请求
- S3向S1返回Promise(3.5,null)的响应
- S1收到Promise(3.5,null)后,提交Accept(3.5,X)的请求
- S3收到Accept(3.5,X)后,向S5返回Accepted(3.5,X)的响应
- S5向S3提交Prepare(4.5)的请求
- S3收到后发现已有设置值X,向S5返回Promise(4.5,X)的响应
- S5收到Promise(4.5,X)后,无条件接受X代替原本的Y作为自己的提案值,提交Accept(4.5,X)的请求
- S3收到Accept(4.5,X)后,向S5返回Accepted(4.5,X)的响应
- S3收到Accept(3.5,X)后,向S5返回Accepted(3.5,X)的响应
S5应该是S1吧
- S3收到Accept(3.5,X)后,向S1返回Accepted(3.5,X)的响应
"Basic Paxos 只能对单个值形成决议" 建议把这句话放在前面,更好理解,不然在阅读的过程中一直再想,要是另一个变量也需要投票,怎么区分呢?阅读过程中到网上找了各种材料才发现,这个算法它压根只能对一个变量进行选举。最后感谢作者的杰作。
@robot88 看了这篇文章后清晰了挺多,感谢作者。 不过有个问题没太弄明白,算法的一个前提是
如果提案节点发现响应的决策节点中,已经有至少一个节点的应答中包含有值了,那它就不能够随意取值了,必须无条件地从应答中找出提案 ID 最大的那个值并接受
不明白为什么要有这种前提。 有了这个前提,一个值设置完成后,不是无法改变了吗?后面prepare对应的promise不都会返回有值吗?还希望能帮忙解答下疑惑
每个instance中选择一个value,多个instance组成状态机。达成共识后确实是不允许改变的啊。
情况四,S5的提案不应该是 P4.5吗,求大佬解惑
@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 去做的。
强一致(不一致的情况不对外界暴露)
Paxos:
- 阶段
- Prepare - 占坑
- 已 accept 其他提案:返回已 accept 的值
- 已 prepare 比当前ID大的提案:沉默(不响应)
- 否则:返回 (提案ID, null)
- Accept - 拉屎
- 已 accept 比当前ID大的提案:沉默
- 已 prepare 比当前ID大的提案:沉默
- 否则:accept 当前提案的值
- Prepare - 占坑
- 特点
- Prepare 过半成功:表明还没有其他提案已过半 accept,当前提案还有机会超越
- 允许竞争
- 可用性也会随节点增加而降低,只是降低速度没那么快 O(N/2);2PC 是 O(N)
- :question: 分出胜负前,若节点 A 已确认了小 ID 的值(但最终结果来自大 ID),此时读值会怎样?
@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的之间的交互,此场景的时间线顺序如下:
- S1向S3提交Prepare(3.5)的请求
- S3向S1返回Promise(3.5,null)的响应
- S1收到Promise(3.5,null)后,提交Accept(3.5,X)的请求
- S3收到Accept(3.5,X)后,向S5返回Accepted(3.5,X)的响应
- S5向S3提交Prepare(4.5)的请求
- S3收到后发现已有设置值X,向S5返回Promise(4.5,X)的响应
- S5收到Promise(4.5,X)后,无条件接受X代替原本的Y作为自己的提案值,提交Accept(4.5,X)的请求
- S3收到Accept(4.5,X)后,向S5返回Accepted(4.5,X)的响应
- S3收到Accept(3.5,X)后,向S5返回Accepted(3.5,X)的响应
S5应该是S1吧
- 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的之间的交互,此场景的时间线顺序如下:
- S1向S3提交Prepare(3.5)的请求
- S3向S1返回Promise(3.5,null)的响应
- S1收到Promise(3.5,null)后,提交Accept(3.5,X)的请求
- S3收到Accept(3.5,X)后,向S5返回Accepted(3.5,X)的响应
- S5向S3提交Prepare(4.5)的请求
- S3收到后发现已有设置值X,向S5返回Promise(4.5,X)的响应
- S5收到Promise(4.5,X)后,无条件接受X代替原本的Y作为自己的提案值,提交Accept(4.5,X)的请求
- S3收到Accept(4.5,X)后,向S5返回Accepted(4.5,X)的响应
- S3收到Accept(3.5,X)后,向S5返回Accepted(3.5,X)的响应
S5应该是S1吧
- S3收到Accept(3.5,X)后,向S1返回Accepted(3.5,X)的响应
我也是这样想
一脑子浆糊大概就是看完这篇文章的感觉