转自https://blog.csdn.net/liweisnake/article/details/69253206
上一章讨论了一种强一致性的情况,即需要分布式事务来解决,本章我们来讨论一种最终一致的算法,paxos算法。
paxos算法是由大牛lamport发明的,关于paxos算法有很多趣事。比如lamport论文最初由故事描述来引入算法,以至于那班习惯数学公式的评委将该论文打回,导致该论文延误了8年才公开发表。另外,google的chubby的作者Mike Burrows说过,世界上只有一种一致性算法,那就是paxos。
两将军问题
为了引入该算法,首先提出一种场景,即两将军问题(见文献1):
两将军问题本质上就是通信被篡改时能否解决一致性问题。这个问题已经被很多人证明不能。(见文献1)。因而由此推及的拜占庭将军问题(多将军问题)也同样不能被解决。
PAXOS算法
这里不再赘述算法的推导及证明过程,参考文献2和3。这里简单描述下算法理解。
基本思想也是两阶段提交。但是与两阶段目的不同。
1. 第一阶段主要目的是选出提案编号最大的proposer。
其描述如下,所有的proposer向超过半数的acceptor提出编号为n的提案,acceptor收到编号为n的请求,会出现两种情况
a. 编号n大于所有acceptor之前已经批准过的proposal的最大编号及内容m。acceptor同意该proposal,响应[n, m]回proposer,并且承诺今后不再批准任何编号小于n的提案。
b. 编号n小于acceptor之前批准过的任意proposal的编号。acceptor拒绝该proposal。
2. 第二阶段尝试对某一proposal达成一致。
proposer收到超过半数的acceptor返回的响应,proposer就会将响应的最大编号[n, m]对应的提案提交到acceptor要求acceptor批准该提案。
acceptor收到最大编号[n, m]的提案,也分为两种情况
a. 未响应过编号大于n的prepare请求。通过该提案。
b. 已响应过编号大于n的prepare请求。拒绝该提案。
整个算法表面上并不难理解,难在实现细节的难易程度和各种异常情况的推导及考虑。如果对上述算法有理解困难的,参考文献4和文献5的例子,其中文献5更容易理解,这里 把他的图贴出来,实际过程就不再重复赘述了。
两个参谋先后提议的场景
两个参谋交叉提议的场景
需要注意的是参谋1在失败时再次发起请求的过程
这里着重强调几个重点。
1. 算法描述里有好几个地方要求投票必须超过半数,这个超过半数恰恰是保证一致的一个必要条件
2. 算法里也有多处要求只选择编号最大的,这种选择编号最大的方式,是一种最为简单经济的达成共识的方法,能够快速在多个冲突中找到一个突破口
3. paxos算法的关键是,如果一个值m被选中了,那么必须保证更高的proposal其值也为m
4. 注意第一阶段比较的是已经批准过的proposal的最大编号,而第二阶段比较的是prepare请求。即第一阶段比较的是第二阶段的结果,而第二阶段比较的是第一阶段的结果,看似很绕,实际上正好是隔离了阶段外的保证,进入第一阶段的我要保证他是新的开始,跟上一阶段没啥关系,而进入第二阶段的我要保证他是从前面阶段来的,而不是新起的一个阶段,有点像是隔离锁,锁住了阶段一到阶段二这个过程。
分布式系统的事务处理 http://coolshell.cn/articles/10910.html
paxos wiki https://en.wikipedia.org/wiki/Paxos_(computer_science)
paxos维基 https://zh.wikipedia.org/wiki/Paxos%E7%AE%97%E6%B3%95
paxos算法例子 https://www.zhihu.com/question/19787937/answer/107750652
paxos算法例子2* http://iunknown.iteye.com/blog/2246484?from=message&isappinstalled=0
Paxos算法1-算法形成理论 http://blog.csdn.net/chen77716/article/details/6166675