Paxos算法详解

问题描述

Paxos算法的目的是解决分布式一致性问题,即一个分布式系统中的各个进程如何就某个值(决议)达成最终一致。当多个进程提出(Propose)不同的值,算法保证最终只有其中一个值被选定,即需要满足:

  1. 只有被提出(Propose)的值才可能被最终选定(Chosen)。
  2. 有且只有一个值会被最终选定(Chosen)。
  3. 进程只会获知到已经确认被选定(Chosen)的值。

三种角色

Paxos将系统中的角色分为提议者 (Proposer),决策者 (Acceptor),和最终决策学习者 (Learner)。每个进程可能充当不止一种角色。

Paxos允许这三种角色在相互的通信中存在消息丢失、延迟、乱序以及重复的故障,但假设消息不会被篡改。它利用大多数 (Majority) 机制保证了2F+1的容错能力,即2F+1个节点的系统最多允许F个节点同时出现故障。

  • Proposer: 提出提案 (Proposal)。Proposal信息包括提案编号 (Proposal ID) 和提议的值 (Value)。
  • Acceptor:参与决策,回应Proposers的提案。收到Proposal后可以接受提案,若Proposal获得多数Acceptors的接受,则称该Proposal被批准。
  • Learner:不参与决策,从Proposers/Acceptors学习最新达成一致的提案(Value)。

两个阶段

Paxos算法通过一个决议分为两个阶段(Learn阶段之前决议已经形成):

  • 第一阶段:Prepare阶段。Proposer向Acceptors发出Prepare请求,Acceptors对收到的Prepare请求进行Promise承诺。
  • 第二阶段:Accept阶段。Proposer收到多数Acceptors承诺的Promise后,向Acceptors发出Propose请求,Acceptors针对收到的Propose请求进行Accept处理。
  • 第三阶段:Learn阶段。Proposer在多数的Acceptors的Accept之后,标志着本次Accept成功,决议形成,将形成的决议发送给所有Learners。

算法的推导

为了保证必须有值被接受,所以Paxos算法中:

P1:Acceptor必须接受(Accept)它所收到的第一个Proposal。

因为我们需要只有一个提案被提出的情况下,仍然能选出一个决议。但这样产生一个问题,如果多个Proposers同时提出Proposal,可能会导致没有任何一个提案被多数Acceptor批准。在P1的基础上,加上一个提案需要半数以上的Acceptor批准才能选定,因此需要Acceptor能够批准多个提案。

这里我们使用一个全局的编号来唯一标识每一个被Acceptor批准的提案(假设当前已经具备这样的外部组件能够生成全局唯一的,编号本文不详细讨论)。此时,提案变成了一个由编号和值组成的组合体。为了保证只有一个值会被最终选定,Paxos进一步提出:

P2:如果值为v的Proposal被选定(Chosen),则任何被选定(Chosen)的具有更高编号的Proposal值也一定为v。

P1和P2,就保证了有且只有一个值会被最终选定。但P2难以实现为具体的算法。我们提出p2的充分条件P2a:

P2a:如果值为v的Proposal被选定(Chosen),则任何被Acceptor批准的的具有更高编号的Proposal值也一定为v。

因为只有首先被批准才有可能被最终选定。但是P2a依然难以实现,因为acceptor很有可能并不知道之前已经被选定的提案的信息(该acceptor恰好不在接受它的多数派中),因此进一步提出P2a的充分条件P2b:

P2b:如果值为v的Proposal被选定(Chosen),则对所有的Proposer,它们提出的的任何具有更高编号的Proposal值也一定为v。

因为只有提案被提出才可能被批准。更进一步,提出充分条件P2c:

P2c:如果编号为n,值为v的提案被提出,必须存在一个由半数以上的Acceptor组成的集合S,满足以下条件中的任意一个:

  • S中没有任何Acceptor曾经批准过编号比n小的提案
  • S中的Acceptors所接受过的编号最大且小于n的提案的值也是v

我们再对P1进行延伸,提出p1的充分条件P1a:

P1a:一个Acceptor只要尚未响应过任何编号大于n的请求,它就可以接受这个编号为n的提案

自此可以引出如下的提案生成算法:


Proposer生成提案

1. Proposer选择一个新的编号n,向超过一半的Acceptors发送请求消息。Acceptor回复信息:

  • 承诺不会批准编号比n小的proposal
  • 如果它已经批准过编号比n小的提案,它会返回已经批准的编号最大且小于n的提案的值。

该请求称为Prepare请求。

2. 如果Proposer收到超过一半Acceptors的回复,它就可以提出编号n,值为v的提案。其中v是收到的回复中编号最大的提案的值,如果没有这样的值 (半数以上的Acceptor都没有批准过任何提案),则可以自由提出任何值。然后,向超过一半的Acceptors发出请求(和前一阶段的Acceptors集合不要求相同,两个集合因为都超过一半,必定存在至少一个公共的Acceptor),请求对方接受提出的提案

该请求称为Accept请求。

Acceptor批准提案

1. 当收到Prepare请求时,如果其编号n大于之前所收到的Prepare消息,则回复。

因为,若一个Acceptor收到一个编号为n的请求,但该Acceptor已经对编号大于n的Prepare请求做出了响应,它肯定不会批准编号为n的提案,因此Acceptor没有必要对这个Prepare请求做出响应

2. 当收到Accept请求时,仅当它没有回复过一个具有更大编号的提案,批准该提案并回复。


算法陈述

阶段一:

  1. Proposer选择一个提案编号n,向Acceptor的某个超过半数的子集成员发送编号为n的Prepare请求
  2. 如果一个Acceptor收到一个编号为n的Prepare请求,且编号n大于该Acceptor已经响应的所有Prepare请求的编号,那么它会将它已经批准过的最大编号的提案(如果有)的值作为响应反馈给Proposer,同时Acceptor会承诺不会再批准任何编号小于n的提案

阶段二:

  1. 如果Proposer收到来自半数以上的Acceptor对于其发出的编号为n的Prepare请求的响应,那么它就会发送一个针对提案(编号n,值v)的Accept请求给Acceptor。注:其中v是收到的回复中编号最大的提案的值,如果没有这样的值 (半数以上的Acceptor都没有批准过任何提案),则可以自由提出任何值。
  2. 如果Acceptor收到这个编号n,值v的Accept请求,只要该Acceptor尚未对编号大于n的Prepare请求做出响应,它就会通过这个提案。

提案的获取

如果一个提案已经被半数以上的Acceptor批准,代表这个提案已经被选定。Leaner获取提案获取这个被选定的提案有如下几种方式:

  1. 一旦Acceptor批准了一个提案,就将提案发送过所有的Learner。缺点是每个Acceptor需要与所有的Leaner进行通信,通信次数为二者的乘积。
  1. 所有Acceptor将它们对提案的批准情况发送给一个主Learner。当主Learner被通知一个提案已经被选定时,它会负责通知其他的Learner。缺点是主Learner带来单点故障问题。
  1. 将方法2的主Learner扩大为一个特定的Learner集合。

一些例子

paxos1.jpg
  • 图中P代表Prepare阶段,A代表Accept阶段。3.1代表从server s1发出的编号为3的proposal。X和Y代表proposal值。
  • 例1中P 4.5的Prepare阶段前,P 3.1已达成多数派,其值X被Accept,然后P 4.5学习到值X。X被最终选定
paxos2.jpg
  • 例2中在P 4.5的Prepare阶段前,P 3.1与s3的accept阶段率先完成,与s1和s2 accept阶段有一定延迟。但P 4.5将学习到X,并将自己的值由Y替换为X。X被最终选定。
paxos3.jpg
  • 例3中在P 4.5的Prepare阶段前,P 3.1与s2和s3的accept阶段尚未完成。当P 4.5提出Prepare请求,s3由于未批准任何提案,将不会返回任何提案值,并承诺不会再批准任何编号小于4的提案。接着,s3收到P 3.1 Accept请求,这个提案不会得到批准。P 4.5的提案在得到s3, s4和s5批准后,Y被最终选定。
paxos4.jpg
  • 例4中两个Proposers交替Prepare成功,而Accept失败,形成活锁(Livelock)。
  • 一个解决活锁的方法是Multi-Paxos算法。

下一节:Multi-paxos算法

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,919评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,567评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,316评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,294评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,318评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,245评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,120评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,964评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,376评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,592评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,764评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,460评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,070评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,697评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,846评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,819评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,665评论 2 354