Basic Paxos

Goal
1.必须并且只能在一个提案上达成一致
2.有且仅有有一个提案能被选中

Requirements
1.安全性(保证paxos不会做出错误的选择)
a)仅有一个提案将被选中
b)如果一个节点已经得知某个提案被选中,那么这个提案一定是被集群所选中
2.活性 (不做错误的选择还不够,我们需要保证paxos能做出正确的选择)(保证活性的前提是集群中的大多数在正常运行并且以合理的及时性进行沟通)
a)最终一定会对某一个提案达成一致
b)如果对一个提案达成一致,那么集群一定会感知到

Components
1.Proposers
a)提出将要被选举的提案
b)处理客户端的请求
2.Acceptors
a)回复来自Proposers的请求
b)回复可以想象成用来达成一致性的投票
c)储存被达成一致的提案还有给出的投票等等
d)最终想要知道集群对哪个提案达成一致

依据上面的要求,我们先设想几种最简单的paxos实现方法

第一种:只有一个Acceptor
缺点:假设一个提案被唯一的acceptor选中之后,这个acceptor stop或者crash掉了,我们没办法在该acceptor恢复之前知道被选中的提案是什么。

解决方案(Quorum)
a)我们需要多个Acceptor(一般来说3,5,7....)
b)当acceptors中的大多数都对一个提案达成一致的时候,这个提案才被选中
c)这样的话如果只有少部分的acceptor stop/crash/partion的时候,集群仍然能够感知到被选中的提案

多个Acceptor带来的问题,如何就某个提案达成一致?

1.尝试一个最简单的方案-->每个acceptor只接受它收到的第一个提案,那么当有多个提案同时提给acceptors时,可能会造成提案没办法被选中的情况,如下图:


image.png

注意:提案被acceptor 接受的时候不代表这个提案被选中,只有大多数acceptors都接受同一个提案的时候,这个提案才意味着被选中。
这违反了Paxos算法的活性要求。那么得出结论,acceptor必须可以多次接受不同的提案(当然前提是在有提案被集群选中之前),换句话说就是如果只有一轮投票的话集群和可能不能对某一个提案达成一致,我们需要更多轮的投票。

2.尝试另一个方案-->每个acceptor接受他收到的每一个提案,那么这样出现集群对不同的提案达成一致,如下图所示。

image.png

S1提出提案red,这时候S1,S2,S3接受提案red,此时集群中的大多数就red提案达成一致,red被选中。之后提案blue被S5提出,之后S3,S4,S5接受blue提案,此时集群中的大多数就blue提案达成一致,blue被选中。这违背了Paxos算法的基本原则--仅有一个提案将被选中。目前能想到规避这个问题的方法就是当提案被提出的时候检查此时是否已经有提案被选中,如果有,则将此次提案换成已经被选中的提案。这样的话即使集群选中了第二次的提案,该提案也和之前选中的提案一致,所以没有影响。
这种方案可以称之为"两阶段协议"
一阶段-->proposer先查询集群是否已经选中某个提案,如果选中,将已经选中的提案替换成原本想要提出的提案
二阶段-->通知其他acceptors接受提出的提案
这种方案是否没有问题?答案是否,考虑如下场景

image.png

过程如下
1)S1提出提案red,发现当前并没有被选中的提案,则通知S1,S2,S3接受提案red
2)在S123还未相应接受提案的请求之前,S5提出提案blue,同样检查是否有被选中的提案,此时S123并没有接受提案red,所以提案blue被发送往S345,并且由于种种原因,对S345接受提案blue的请求比S123接受提案red的请求更早完成,那么此时集群选中提案blue
3)当S345完成接受提案之后,S123也完成接受提案red,此时S3存储的提案被改写成red,集群此时选中的提案为red。
很不幸,我们又违反了Paxos的基本原则。。

对于这个问题我们还是有解决方案的-->如果集群已经选定了某个提案,那么任何带有竞争关系的提案必须被放弃,在上面那个case中,S3已经接受了提案blue,他必须拒绝提案red
为了做到这一点,我们必须对提案的进行排序,以便达到新的提案可以拒绝老的提案的需求(因为S3作为acceptor并不知道存储在自身的提案是否被集群选中,所以他需要有一个方案能判定后来的提案能否接受,所以我们需要排序)

那么问题来了,如何对提案进行排序?
我们需要给每一个提案一个唯一的proposal_no,并且有如下规则
1)proposal_no越大,proposal优先级越高
2)proposer提出提案时选择的proposal_no要比之前使用过的更高
我们可以这样设计一个简单的proposal_no = round_no + server_id
server_id是每一个server的编号,他是唯一的,把他加入proposal_no可以保证当某个proposer提出proposal的时候新的proposal_no不会被其他proposer生成过。
round_no会随着时间增加,每个proposer都保留maxRoundNo(此proposer见过的最大的round_no,此数据必须落盘,如果该proposer刚从故障中恢复,请不要使用该maxRoundNo),每次新的proposal提出的时候令round_no=maxRoundNo+N

总结一下,目前方案还是两阶段
Phase1:广播Prepare rpc请求
1)寻找是否有被选中的提案
2)阻塞正在提交中老提案
Phase2:广播Accept rpc请求
1)请求Acceptors接受提案

我们用伪代码表示下:
Prepare阶段
1)Proposer生成一个新的proposal_no
2)Proposer调用prepare(proposal_no)方法请求每一个server
3)Acceptors响应prepare(proposal_no)方法

  //minProposalNo 此Proposer见过最大的proposal_no
  //acceptedProposalNo 接受提案时的proposal_no
  //acceptedValue 接受的提案
  if(proposal_no > minProposalNo){
      minProposalNo = proposal_no;
  }
  return acceptedProposalNo,acceptedValue;

4)当Proposer收到大多数Acceptors的回复时
//value 本次提案
//acceptedValue 从大多数Acceptors返回的最大acceptedProposalNo对应的acceptedValue

  if(List<acceptedValue> != null){
    value = acceptedValue
  }

Accept阶段
5)Proposer 调用 accept(proposal_no,value)请求每一个server
6)Acceptors处理accept请求

  if(proposal_no >= minProposalNo){
    acceptedProposalNo = proposal_no = minProposalNo;
  }
  return minProposalNo;

7)如果Proposer接收到了大多数Acceptors的返回

  if(any result > proposal_no){
    //返回第一步重新开始
    goto 1;
  }else{
    value has been choosen
  }

注意:acceptedProposalNo,acceptedValue,minProposalNo必须在Acceptors服务器中可靠存储。

下面来看几个例子,要搞清楚为何Paxos能正常的工作关键就时分析出新的Proposal发出prepare请求的时间点。该时间点可以出现在三个位置,分别如下

1.当新的proposal到达时,之前的proposal已经完全执行完毕换句话说已经有提案被选定


image.png

P 3.1 P表示Prepare阶段, 3表示proposal_no,1表示server_id,意思就是S1发送prepare请求到S1,S2,S3服务器。
A 3.1 X表示Accept阶段,3表示proposal_no,1表示server_id,X是提案
在这种情况下,P 4.5 发起后检测到已有选定的提案X,则将自己的提案从Y更换成X

2.当新的proposal到达时,之前的proposal执行了一半,部分server已经接受了提案但是还未选定,而且新的proposal在prepare阶段能感知到之前proposal 执行accept的结果


image.png

此时的情况和1一样,在新的proposal prepare阶段执行的server恰好和老的proposal accept阶段执行的server有重合-->S3,那么S5发起的proposal将会将提案由Y改成X并调用accept

3.当新的proposal到达时,之前的proposal执行了一半,部分server已经接受了提案但是还未选定,而且新的proposal在prepare阶段不能感知到之前proposal 执行accept的结果


image.png

新的proposal prepare阶段无法感知老proposal accept阶段执行结果,所以当新的proposal发起accept阶段时,使用的还是新的提案Y并且在S5,S4上执行成功,这时候老的proposal accept阶段到达,因为accept也必须要请求到集群中的大多数server,所以必然会与新的proposal 的prepare阶段server有交集,这时发现S3上的proposal_no(4.5) > 自己的proposal_no(3.1)则老的proposal accept阶段会被放弃,并且回到1重新来过。

Liveness

image.png

提案间的竞争可能会导致Basic Paxos失活(无法选择一个提案)
如上图所示
P3.1在执行A3.1X之前,P3.5到达,则A3.1X放弃并回到步骤1重新发起新的proposal P4.1,不巧的是此时A3.5Y又发现P4.1已经执行,只能放弃并且回到步骤1重新开始,如此循环往复集群将永远无法就某一个提案达成一致。
解决方案
在A3.1X被拒绝之后不要马上发起新的proposal而是等待一个合理的时间让A3.5Y能够有机会完成。

原视频在此,真的将的非常好
https://www.bilibili.com/video/av16805461/

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

推荐阅读更多精彩内容

  • 原文:Paxos Made Simple作者:Leslie Lamport时间:01 Nov 2001 1 Int...
    随安居士阅读 1,566评论 1 2
  • Paxos在分布式系统中的重要性无需多言。我们能在网络上找到非常多解析Paxos原理的文章,这些文章大部分只讲协议...
    远方也是苟且阅读 947评论 0 0
  • Paxos是什么 Paxos算法是基于消息传递且具有高度容错特性的一致性算法,是目前公认的解决分布式一致性问题最有...
    jiangmo阅读 1,537评论 0 6
  • 0.前言 本文记录笔者学习和理解区块链共识算法Paxos的点滴,文章比较长,需要耐心来细细琢磨,笔者也是苦战了一个...
    WallisW阅读 3,233评论 2 14
  • paxos算法在分布式领域具有非常重要的地位。但是Paxos算法有两个比较明显的缺点:1.难以理解 2.工程实现更...
    阿斯蒂芬2阅读 1,101评论 0 4