Paxos 算法分析

Paxos 的核心思想:“与其预测未来,不如限制未来”。
 

背景:

Paxos算法是莱斯利·兰伯特(英语:Leslie Lamport,LaTeX中的“La”)于1990年提出的一种基于消息传递且具有高度容错特性的共识(consensus)算法。
分布式系统中的节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing)。

基于消息传递通信模型的分布式系统,不可避免的会发生以下错误:进程可能会慢、被杀死或者重启,消息可能会延迟、丢失、重复,在基础 Paxos 场景中,先不考虑可能出现消息篡改即拜占庭错误的情况。Paxos 算法解决的问题是在一个可能发生上述异常的分布式系统中如何就某个值达成一致,保证不论发生以上任何异常,都不会破坏决议的共识。一个典型的场景是,在一个分布式数据库系统中,如果各节点的初始状态一致,每个节点都执行相同的操作序列,那么他们最后能得到一个一致的状态。为保证每个节点执行相同的命令序列,需要在每一条指令上执行一个“共识算法”以保证每个节点看到的指令一致。一个通用的共识算法可以应用在许多场景中,是分布式计算中的重要问题。因此从20世纪80年代起对于共识算法的研究就没有停止过。

为描述Paxos算法,Lamport虚拟了一个叫做Paxos的希腊城邦,这个岛按照议会民主制的政治模式制订法律,但是没有人愿意将自己的全部时间和精力放在这种事情上。所以无论是议员,议长或者传递纸条的服务员都不能承诺别人需要时一定会出现,也无法承诺批准决议或者传递消息的时间。但是这里假设没有拜占庭将军问题(Byzantine failure,即虽然有可能一个消息被传递了两次,但是绝对不会出现错误的消息);只要等待足够的时间,消息就会被传到。另外,Paxos岛上的议员是不会反对其他议员提出的决议的。

对应于分布式系统,议员对应于各个节点,制定的法律对应于系统的状态。各个节点需要进入一个一致的状态,例如在独立Cache的对称多处理器系统中,各个处理器读内存的某个字节时,必须读到同样的一个值,否则系统就违背了一致性的要求。一致性要求对应于法律条文只能有一个版本。议员和服务员的不确定性对应于节点和消息传递通道的不可靠性。

 

相关术语:

Proposer:  提议发起者
Acceptor:  提议接受者
Leaner:  提议学习者(只能“学习”被批准的提案)
Proposal Value:  提议的值
Proposal Number:   提议编号,全序,不能冲突
Proposal:   提议 = 提议的值 + 提议编号
 

核心算法分析:

记 [n, v] 为编号 n 、值 v 的提案
记 (m, [n, v]) 为承诺了 Prepare(m)请求,并接受提议[n, v]
 
按4个步骤走:
第一阶段 A:
Proposer 选择一个提议编号 n, 向所有的 Acceptor 广播 Propare(n)
 
第一阶段 B :
Acceptor 接收到 Prepare(n)请求,
如果提议编号 n 比之前接收到的 Prepare编号小,则不予理会
如果提议编号 n 比之前接收到的 Prepare 编号大或者相等,则承诺不会接受提议编号比 n 小的提议,并且带上之前接受的提议中编号小于 n 的最大的提议
 
第二阶段 A:
Proposer 得到了大多数 Acceptor 的承诺后,
如果没有发现有一个 Acceptor 接受过一个提案,那么向所有的 Acceptor 发起自己的值和编号,
如果发现有 Acceptor 接受过提案,那么从所有接受过的值中选择对应提议编号最大的,作为提议的值,但是提议编号仍然为 n
 
第二阶段 B :
Acceptor 接收到 Accept[n, v]提议请求, 如果该提议编号不违反自己做过的承诺,则接受该提议。
 
 

数学证明:

Paxos 原命题:
如果一个提议 [n0, v0] 被大多数 Acceptor 接受,那么不存在提议 [n1, v1] 被大多数 Acceptor 接受,其中 n0 < n1, v0 != v1 
 
Paxos 原命题加强:
如果一个提议 [n0, v0] 被大多数 Accptor 接受,那么不存在 Acceptor 接受提议 [n1, v1] ,其中 n0 < n1, v0 != v1 
 
Paxos 原命题进一步加强:
如果一个提议 [n0, v0] 被大多数 Acceptor 接受,那么不存在 Proposer 发出提议 [n1, v1],其中 n0 < n1, v0 != v1
 
如果 “Paxos 原命题进一步加强” 成立,那么 “Paxos 原命题” 显然成立。
用数学归纳法证明:
假设,提议 [n0, v] 被大多数 Acceptor 接受, 那么提议 [n0, v] 到 提议[n, v]对应的值都为 v,其中 n 不小于 n0
这里对 n 进行归纳假设,当 n = n0 时,结论显然成立。
设 n = k 时结论成立, 即如果提议 [n0, v] 被大多数Acceptor 接受, 那么提议[n0, v] 到 [k, v]对应的值都为 v, 其中 k 不小于 n0
当 n = k + 1 时, 如果提议  k + 1 不存在, 结论成立。
如果 提议 k + 1 存在, 对应的值为 v1,因为提议 n0 已经被大多数 Acceptor 接受, k + 1 的 Prepare 被大多数Acceptor 承诺并返回结果。
基于两个大多数集合必有交集,得出提议 k + 1的第一阶段 B 有带提议回来.
那么 v1 时从返回的提议中选出来的,不妨设这个值是选自提议[x, v1]
由第二阶段 B, 因为 x 是返回的提议中编号最大,所以 x >= n0,且此时 x < n(k + 1), 则 v1 = v。
综上,由  n = k 结论成立, 可以推导出 n = k + 1 成立。
于是对于任意不小于提议编号 n0的提议 n,对应的值都为 v.
命题成立。
 
小结:
1. 极端情况下,提案的选定过程可能陷入死循环
原因分析:todo
 
解决思路:通过选取主 Proposer 保证算法的活性
 
2.  Paxos 协议一般是 2F + 1 个 Acceptor ?允许最多 F 个 Acceptor 宕机,而保证协议能够正常进行,得到一个确定的值。
 
3.  为什么 Acceptor 需要做一个承诺?(不会接受提议编号比 n 小的提议)
可以确保 Proposer 在第二阶段 A 中的选择不会收到未来变化影响。
 
4. 为什么第二阶段 A 要从返回结果中选择一个编号最大的那个值?
这样选出来的编号一定是不小于已经被大多数Acceptor 接受的编号,而且这个编号对应的值一定是被 chosen 的那个值。
 
5. .. 待补充
 
参考:
Paxos 论文原文:https://lamport.azurewebsites.net/pubs/paxos-simple.pdf
维基百科:  https://zh.wikipedia.org/wiki/Paxos%E7%AE%97%E6%B3%95
InfoQ: 微信 PaxosStore:  深入浅出 Paxos 算法协议 https://www.infoq.cn/article/wechat-paxosstore-paxos-algorithm-protocol
书籍:《从 Paxos 到 ZooKeeper》p36

你可能感兴趣的:(算法基础,架构,理论基础)