Paxos算法

  转载请注明出处http://www.cnblogs.com/dvd0423/p/4185697.html

  浮躁的人请绕道,这篇文章不适合你。

  把Paxos作为分布式系统系列的第一篇,是因为我迫不及待的想告诉别人这个算法是多么牛逼。相比于Map/Reduce架构、一致性Hash、两阶段提交等等,我觉得Paxos是一个让人第一次看到会感觉废话连篇,再仔细品味会拍手称赞的算法。Paxos算法最初由lamport提出,他第一次提出时模拟的是一个叫Paxos的希腊城邦立法的问题。由于这个算法太抽象了,所以他在两篇论文中提出都没多少人在意,直到后来谷歌chubby用了此算法别人才明白这个算法的精髓。这里我们只介绍它的中心思想,具体细节有很多,可以详细看看参考文献[1,2]中lamport的论文。

  Paxos算法是一个基于消息传递机制的一致性算法,不同于共享内存机制。共享内存机制相当于大家在一起开会产生最终决议,是集中式的;而消息传递方式中人与人之间不知道各自在干什么,只能通过繁琐的沟通才能一点点了解,是分布式的。有点像openMP与MPI的区别。我个人更喜欢把它看作选举算法来理解,而不是一致性算法。

问题模型   

  城邦立法问题(和原模型大同小异):小岛上有议长、议员、信使、法律提议者、民众这些人。法律的产生由议长主持,提议者提出方案交给各个议员,议员按多数原则投票决定最终法律条文,而议员投票不需要在一起开会,所以他们可以在任何地方投票,投完票后只能由信使传递给议长,议长根据最终决议产生法律,并告知群众。

  大家看到这里可能会觉得这不是很简单的事情吗?如果上述问题中所有人都100%尽职,并步调一致,那么这确实是一件很简单都事。关键问题在于现实世界中议长可能突然死了,这时候要换议长;一部分议员度假1天回家后才投票;一些信使中途也死了,或者中途干活去了。这些导致了消息传递的不可靠,从而导致了选举结果的混乱。比如本来决定了1号提议者的方案(共有5票最多),但在对外公布之前又有两名信使刚把议员的消息带到议长那里,而他们选的都是2号提议者(本来是4票)的方案。这样最终2号提议者应该是多数,所以议长要改变最终议案。消息传递的不可靠和不同步导致了决议的不一致。

算法实现

  而Paxos算法就是提出一些约束条件,使立法顺利进行,就算有意外发生也能产生最终法案的策略。它很好的解决了一致性问题。要保证一致性就要满足一些条件,总结起来就是三条看似废话的安全属性:

  •只有提议者的方案能成为法律,

  •最终只能选一个人的提议,并且

  •只有议长公布后大家才知道最终法案的内容。

  显然,只要满足上面的条件的算法就都能保证投票过程不出问题。好,现在Paxos算法正式开始:

  如果仅有一个提议者提出了一个决议,我们也希望能选择一个决议。所以下面条件需要成立:

  P1一个议员必须无条件同意他收到的第一个决议。

  在满足P1的情况下如果每个议员接收到的第一个决议都不同,则没有决议被多数派批准,所以为了避免这种情况发生一个议员就必须可以批准多个议案。每个提议者可以多次提议,而每次提议形成不同但议案,每个议案可以由唯一的编号决定,在这里我们的议案设置为{编号,内容}结构,用数字表示为{n, v}。我们允许选择多个议案,但被选为最终法律的所有议案的内容v都相同。也就是:

  P2 如果一个议案{n, v}被最终选取,那么所有后来被选择的编号>n的议案内容也都是v。

  因为编号是顺序的,所以P2保证了第二条安全属性。议案至少被一个议员批准才可能被最终选取。因此P2等价于下面推论:

  P2a 如果最终被选择的议案是{n, v},那么任何议员批准的编号>n的议案内容都是v。

  首先我们通过P1保证了某些议案被选择。由于通信的异步性,在一个议员C没有收到过任何议案的情况下,可能已经产生了最终决议。而这时候如果一个新的提议者提出了内容不同的、有更高编号的全新议案{N, V},则根据P1,C议员必须接受{N, V}。但这样就违反了P2a。为了解决这个矛盾我们要把P2a的约束加强为:

  P2b如果最终被选择的议案是{n, v},那么以后任何提议者提出的的编号>n的议案内容都是v。

  这样通过P2b就能推出P2a,从而推出P2。而如果最终议案满足P2b条件,则选取议案{n, v}的多数派集合S要满足一下条件:

  P2c对于任意的v和n,如果议案{n, v}被提出,那么存在一个由议员的多数派组成的集合S,或者a) S中没有议员批准过编号小于n的议案,或者b) 在S的任何议员批准的所有议案(编号小于n)中,v是编号最大的议案的决议内容。

  通过保持P2c,就能保持P2b。为了保证P2c,准备提出议案{n, v}的提议者必须知道所有编号小于n的议案中已经或者将要被多数派议员批准的编号最大的那个(如果有的话)。提议者获知已经被批准的议案很简单,但是预知未来将要被批准的议案很难。所以这个提议者要求议员不能批准任何编号比n小的议案。这就引出了以下提议者算法,这就是一个两阶段提交算法:

  1.提议者选择一个新编号n,向某个议员集合中的所有成员发送请求,并要求回应:

  a)一个绝不批准编号小于n的议案的承诺,

  b)编号小于n的议案中他已经批准的编号最大的议案(如果存在的话)。否则回应无。

  这样的请求称为prepare请求,没有内容,所以不是议案!这是第一阶段。

  2.如果提议者A收到议员的回应,那么就可以发送提交一个议案{n, vA}的请求,其中vA要么是1中b)的议案内容vb,(vb内容为NULL时)要么就是提议者自己的新的议案内容vA。这个请求为accept请求,此为第二阶段。

  上面描述了提议者的操作,那么议员要满足什么要求呢?首先议员可以随便忽略任何请求,这样议员可以弃权不投票,但是不能乱投票,下面说明议员回应请求的操作要求:

  议员可以批准一个编号为n的议案,当且仅当它没有回应过一个编号大于n的prepare请求。

  即议员如果回应了一个编号为n+1的请求,就不会再回应编号为n的请求。议员只需要保存它已经批准的最高编号的议案{n, v},以及它已经回应的所有prepare请求的最高编号N。

  至此Paxos决策过程完成。现在让我们结合提议者和议员的行为将算法分为两个阶段

阶段1:

  a) 提议者选择一个议案编号n,向议员的多数派发送编号为n的prepare请求。

  b) 议员:如果接收到的prepare请求的编号n大于它已经回应的任何prepare请求,它就回应已经批准的编号最高的议案{m, k},并承诺不再回应任何编号小于n的议案.

阶段2:

  a) 提议者:如果收到了多数议员对prepare请求(编号为n)的回应,它就向这些议员发送议案{n, v}的accept请求,其中v是所有回应中编号最高的议案的决议内容即阶段1的k,如果回应说还没有议案,则v是提议者自己的议案内容。

  b) 议员:如果收到了议案{n, v}的accept请求,它就批准该议案,除非它已经回应了一个编号大于n的议案。

公布最终法律

  至此就可以保证最终法律的产生。但是人民群众还不知道是不是已经产生了最终法律。群众必须找到一个被多数派议员批准的议案,才能知道最终法律产生了。

  一个显而易见的算法就是,让每个议员在批准议案时通知所有的群众。于是群众可以尽快知道选择的决议,但是要求每个议员通知每个群众——需要的消息个数等于群众数和议员数的乘积,这样太浪费信使。所以可以只告诉议长,然后由议长公布。但是议长也可能突然死了,所以要有多个议长同时主持。

  第二种方法如果群众需要知道是否已经选择了一个决议,他可以让提议者根据上面的算法提出一个议案或者自己提议,prepare请求有回应,并且回应一个议案{m, k}。则说明最终法律已经产生。

总结

  太耗脑细胞,写完全文我又饿了。出去吃夜宵喽。

by 糖球

参考文献

[1] The part-time parliament, Lamport, ACM Transactions on Computer Systems 16(2):133-169, 1998

[2] Paxos made simple, Lamport, SIGACT News 32(4):18-25, 2001.

[3] paxos和分布式系统. 百度基础架构部

时间: 2024-12-20 03:34:27

Paxos算法的相关文章

【转】Paxos算法细节详解

最近研究zookeeper因此就学习了一下paxos算法,一直没太看懂,今天找到了这篇文章描述的很清晰,转自:http://www.cnblogs.com/endsock/p/3480093.html Paxos分析 最近研究paxos算法,看了许多相关的文章,概念还是很模糊,觉得还是没有掌握paxos算法的精髓,所以花了3天时间分析了libpaxos3的所有代码,此代码可以从https://bitbucket.org/sciascid/libpaxos 下载.对paxos算法有初步了解之后,再

一步一步理解Paxos算法

一步一步理解Paxos算法 背景 Paxos 算法是Lamport于1990年提出的一种基于消息传递的一致性算法.由于算法难以理解起初并没有引起人们的重视,使Lamport在八年后重新发表到 TOCS上.即便如此paxos算法还是没有得到重视,2001年Lamport用可读性比较强的叙述性语言给出算法描述.可见Lamport对 paxos算法情有独钟.近几年paxos算法的普遍使用也证明它在分布式一致性算法中的重要地位.06年google的三篇论文初现“云”的端倪,其中的chubby锁服务使用p

【转】Paxos算法深入分析

http://blog.csdn.net/anderscloud/article/details/7175209 在分布式系统设计领域,Paxos可谓是最重要一致性的算法.Google的大牛们称   All working protocols for asynchronous consensus we have so far encountered have Paxos at their core. 可见此算法的地位.网络上讨论此算法的文章多如牛毛,但大多数让人看了之后仍然是一头雾水,就连维基百

【转】Paxos算法1-算法形成理论

——转自:{老码农的专栏} Paxos算法的难理解与算法的知名度一样令人敬仰,从我个人的经历而言,难理解的原因并不是该算法高深到大家智商不够,而在于Lamport在表达该算法时过于晦涩且缺乏一个完整的应用场景.如果大师能换种思路表达该算法,大家可能会更容易接受: 首先提出算法适用的场景,给出一个多数读者能理解的案例 其次描述Paxos算法如何解决这个问题 再次给出算法的起源(就是那些希腊城邦的比喻和算法过程) Lamport首先提出算法的起源,在没有任何辅助场景下,已经让很多人陷于泥潭,在满脑子

分布式理论之一:Paxos算法的通俗理解

维基的简介:Paxos算法是莱斯利·兰伯特(Leslie Lamport,就是 LaTeX 中的"La",此人现在在微软研究院)于1990年提出的一种基于消息传递且具有高度容错特性的一致性算法. Paxos算法目前在Google的Chubby.MegaStore.Spanner等系统中得到了应用,Hadoop中的ZooKeeper也使用了Paxos算法,在上面的各个系统中,使用的算法与Lamport提出的原始Paxos并不完全一样,这个以后再慢慢分析.本博文的目的是,如何让一个小白在半

底层算法系列:Paxos算法

关于算法,面太广.本系列只研究实际应用中遇到的核心算法.了解这些算法和应用,对java码农进阶是很有必要的. 对于Paxos学习论证过程中,证实一句话:有史以来学习paxos最好的地方wiki:Paxos (computer science) 目录 1.背景 2.Paxos算法 3.Muti-Paxos算法 4.Muti-Paxos在google chubby中的应用 ===============正文分割线============================ 一.背景 Paxos 协议是一

Paxos算法介绍

Paxos算法是为了实现分布式环境中为保证数据的一致性而设计的,在一个分布式系统中,通过投票的方式来确定一个值(决议).只不过这个步骤分为两步: 准备阶段(prepare)和批准阶段(accept). 同时又分为若干角色,以下都可以兼任. proposer 信使 acceptor 决策者 learner 学习者(学习最终决策) 准备阶段: 一个proposer向多个acceptor发出提案,每个提案有一个数字编号(递增的), 如果多数acceptor接受了该提案,则进入批准阶段. 当然也可以拒绝

Paxos算法之旅(四)zookeeper代码解析

ZooKeeper是近期比较热门的一个类Paxos实现.也是一个逐渐得到广泛应用的开源的分布式锁服务实现.被认为是Chubby的开源版,虽然具体实现有很多差异.ZooKeeper概要的介绍可以看官方文档:http://hadoop.apache.org/zookeeper 这里我们重点来看下它的内部实现. ZooKeeper集群中的每个server都要知道其他成员,通过在配置文件zoo.cfg中作如下配置实现: tickTime=2000 dataDir=/var/zookeeper/ clie

【转】Paxos算法3-实现探讨

——转自:{老码农的专栏} 前两篇Paxos算法的讨论,让我们对paxos算法的理论形成过程有了大概的了解,但距离其成为一个可执行的算法程序还有很长的路要走,原因是很多的细节和错误未被考虑.Google Chubby的作者说,paxos算法实现起来远没有看起来简单,原因是paxos的容错仅限于server crash这一种情况,但在实际工程实现时要考虑磁盘损坏.文件损坏.Leader身份丢失等诸多的错误. 1. Paxos各角色的职能 在paxos算法中存在Client.Proposer.Pro