Paxos算法初探

Posted KC的万花筒

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Paxos算法初探相关的知识,希望对你有一定的参考价值。

【公号重开前言】

本来想过无数个开篇的文章,包括IT人员的猝死、邪马台国的初探、信息安全的经历、甚至是直接同人小说开篇。最后没想到是这个不甚熟悉的算法的初步研究。

我是各类信息的搬运工和加工者,我不要粉丝,就现在这些挺好,大家静静的听我的故事就好。




【Paxos算法是什么?】

Paxos算法解决的问题是一个分布式系统如何就某个值(决议)达成一致。一个典型的场景是,在一个分布式数据库系统中,如果各节点的初始状态一致,每个节点都执行相同的操作序列,那么他们最后能得到一个一致的状态。为保证每个节点执行相同的命令序列,需要在每一条指令上执行一个“一致性算法”以保证每个节点看到的指令一致,是分布式计算中的重要问题。

 

【Paxos的历史】

Paxos算法是Lamport于1990年提出的一种基于消息传递的一致性算法——大家表示算法看不懂

结果Lamport在八年后重新发表到 TOCS上——吃瓜群众表示看是看不懂

2001年Lamport用可读性比较强的叙述性语言给出算法描述——部分群众放下了瓜

2006年google的三篇论文初现“云”的端倪,其中的chubby锁服务使用paxos作为chubbycell中的一致性算法——吃瓜群众放下了瓜,拿起了paxos。

 

【Paxos的两大原则】

安全原则---保证不能做错的事

1. 只能有一个值被批准,不能出现第二个值把第一个覆盖的情况

2. 每个节点只能学习到已经被批准的值,不能学习没有被批准的值

存活原则---只要有多数服务器存活并且彼此间可以通信最终都要做到的事

1. 最终会批准某个被提议的值

2. 一个值被批准了,其他服务器最终会学习到这个值

 

【Paxos的两个角色】

Proposer(以下简称P员工团)

提议发起者,处理客户端请求,将客户端的请求发送到集群中,以便决定这个值是否可以被批准。

Acceptor(以下简称A老板团)

提议批准者,负责处理接收到的提议,他们的回复就是一次投票。会存储一些状态来决定是否接收一个值

 

【Paxos的初步分析】

假设每一个家庭(服务器)存在一个P员工和一个A老板,那么会发生哪些事情呢?

 

只有一个A老板,她(额,霸道总裁)做决定是否批准一个值

每个P员工都提议一个报告(值)给霸道总裁来批准,然后霸道总裁批准一个值作为最终的值。

但是有没有发现,如果每个员工都提交报告申请的话,霸道总裁也会被累死(Acceptorcrash),如果霸道总裁病了,就不知道哪个P员工的报告被选择了,只能让霸道总裁睡一觉(重启),这里就违背了存活原则。

 

有很多个A老板的情况

为了解决这个问题,就必须要用到一种多数选择的方法。A老板形成董事会投票,然后只有其中的多数批准了一个报告(值),这个报告(值)才可以确实是被最终被批准的。

为了达到目的也需要一些技巧:

霸道总裁A老板说了,第一份报告我都批,保证有一个报告可以确认;

但是这时候发生了,没有报告被多数批准,霸道总裁头疼了,那我每一个都批可以么?

结果很多份报告(值)都批出来了,违背了一致性原则。

于是霸道总裁A老板又想了个辙,允许某些后提交的P员工二次提交,如果发现前面的值已经被批准了,P员工必须放弃自己的原先选择,改成批准的值,这就是二段提交原则了。

这个时候,出现了插队的P员工,一插队倒好,又出现多份报告了,二段提交原则还是有漏洞。

这个时候,提议排序出现了,只要是霸道总裁A老板确定了报告,后续所有冲突的报告都被舍弃(看什么看,就是你排后面的,拿报告滚出去)

A老板把报告分了个序,写了个ID,规定ID越大,优先级越高。

之后顺顺利利,总裁批员工的报告不亦乐乎。

图片来自百度《实习女总裁》

 

【小贴士】

提议ID生成算法

在Google的Chubby论文中给出了这样一种方法:假设有n个proposer,每个编号为ir(0<=ir<n),proposor编号的任何值s都应该大于它已知的最大值,并且满足:s %n = ir => s = m*n + ir

proposer已知的最大值来自两部分:proposer自己对编号自增后的值和接收到acceptor的reject后所得到的值

以3个proposer P1、P2、P3为例,开始m=0,编号分别为0,1,2

1. P1提交的时候发现了P2已经提交,P2编号为1 > P1的0,因此P1重新计算编号:new P1 = 1*3+0 = 4

2. P3以编号2提交,发现小于P1的4,因此P3重新编号:new P3 = 1*3+2 = 5

 

二段提交

prepare 阶段:

1. Proposer 选择一个提案编号 n 并将 prepare 请求发送给Acceptors 中的一个多数派;

2. Acceptor 收到prepare 消息后,如果提案的编号大于它已经回复的所有 prepare 消息,则 Acceptor 将自己上次接受的提案回复给 Proposer,并承诺不再回复小于 n 的提案;

acceptor阶段:

1. 当一个 Proposer 收到了多数 Acceptors 对 prepare 的回复后,就进入批准阶段。它要向回复 prepare 请求的 Acceptors 发送 accept 请求,包括编号 n 和根据 prepare阶段 决定的 value(如果根据 prepare 没有已经接受的 value,那么它可以自由决定 value)。

2. 在不违背自己向其他Proposer 的承诺的前提下,Acceptor 收到accept 请求后即接受这个请求。

prepare阶段有两个目的,第一检查是否有被批准的值,如果有,就改用批准的值。第二如果之前的提议还没有被批准,则阻塞掉他们以便不让他们和我们发生竞争,当然最终由提议ID的大小决定。

 



以上仅仅是Paxos的一个基础角色场景,下面我们看复杂的。

 

【Paxos的四个角色】

Proposer :提议者

Acceptor:决策者

Client:产生议题者

Learner:最终决策学习者

增加了2个打酱油的角色,C和L。

 

【Paxos的深化分析】

  1. Proposer提出议题

  2. Acceptor初步接受 或者 Acceptor初步不接受

  3. 如果上一步Acceptor初步接受则Proposer再次向Acceptor确认是否最终接受

  4. Acceptor 最终接受 或者Acceptor 最终不接受


有2个Client(老板,老板之间是竞争关系)和3个Acceptor(政府官员):

 

  1. 现在需要对一项议题来进行paxos过程,议题是“A项目我要中标!”,这里的“我”指每个带着他的秘书Proposer的Client老板。

  2. Proposer当然听老板的话了,赶紧带着议题和现金去找Acceptor政府官员。

  3. 作为政府官员,当然想谁给的钱多就把项目给谁。

  4. Proposer-1小姐带着现金同时找到了Acceptor-1~Acceptor-3官员,1与2号官员分别收取了10比特币,找到第3号官员时,没想到遭到了3号官员的鄙视,3号官员告诉她,Proposer-2给了11比特币。不过没关系,Proposer-1已经得到了1,2两个官员的认可,形成了多数派(如果没有形成多数派,Proposer-1会去银行提款在来找官员们给每人20比特币,这个过程一直重复每次+10比特币,直到多数派的形成),满意的找老板复命去了,但是此时Proposer-2保镖找到了1,2号官员,分别给了他们11比特币,1,2号官员的态度立刻转变,都说Proposer-2的老板懂事,这下子Proposer-2放心了,搞定了3个官员,找老板复命去了,当然这个过程是第一阶段提交,只是官员们初步接受贿赂而已。故事中的比特币是编号,议题是value。

这个过程保证了在某一时刻,某一个proposer的议题会形成一个多数派进行初步支持;

  1. 现在进入第二阶段提交,现在proposer-1小姐使用分身术(多线程并发)分了3个自己分别去找3位官员,最先找到了1号官员签合同,遭到了1号官员的鄙视,1号官员告诉他proposer-2先生给了他11比特币,因为上一条规则的性质proposer-1小姐知道proposer-2第一阶段在她之后又形成了多数派(至少有2位官员的赃款被更新了);此时她赶紧去提款准备重新贿赂这3个官员(重新进入第一阶段),每人20比特币。刚给1号官员20比特币, 1号官员很高兴初步接受了议题,还没来得及见到2,3号官员的时候

  2. 这时proposer-2先生也使用分身术分别找3位官员(注意这里是proposer-2的第二阶段),被第1号官员拒绝了告诉他收到了20比特币,第2,3号官员顺利签了合同,这时2,3号官员记录client-2老板用了11比特币中标,因为形成了多数派,所以最终接受了Client2老板中标这个议题,对于proposer-2先生已经出色的完成了工作;

  3. 这时proposer-1小姐找到了2号官员,官员告诉她合同已经签了,将合同给她看,proposer-1小姐是一个没有什么职业操守的聪明人,觉得跟Client1老板混没什么前途,所以将自己的议题修改为“Client2老板中标”,并且给了2号官员20比特币,这样形成了一个多数派。顺利的再次进入第二阶段。由于此时没有人竞争了,顺利的找3位官员签合同,3位官员看到议题与上次一次的合同是一致的,所以最终接受了,形成了多数派,proposer-1小姐跳槽到Client2老板的公司去了。

  4. Paxos过程结束了,这样,一致性得到了保证,算法运行到最后所有的proposer都投“client2中标”所有的acceptor都接受这个议题,也就是说在最初的第二阶段,议题是先入为主的,谁先占了先机,后面的proposer在第一阶段就会学习到这个议题而修改自己本身的议题,因为这样没职业操守,才能让一致性得到保证,这就是paxos算法的一个过程。原来paxos算法里的角色都是这样的不靠谱,不过没关系,结果靠谱就可以了。该算法就是为了追求结果的一致性。


【小贴士】

例子1:

例子2:

zookeeper常常用来做分布式事务锁。Zookeeper所使用的zad协议也是类似paxos协议的。所有分布式自协商一致性算法都是paxos算法的简化或者变种。Client是使用zookeeper服务的机器,Zookeeper自身包含了Acceptor, Proposer, Learner。Zookeeper领导选举就是paxos过程,还有Client对Zookeeper写Znode时,也是要进行Paxos过程的,因为不同Client可能连接不同的Zookeeper服务器来写Znode,到底哪个Client才能写成功?需要依靠Zookeeper的paxos保证一致性,写成功Znode的Client自然就是被最终接受了,Znode包含了写入Client的IP与端口,其他的Client也可以读取到这个Znode来进行Learner。也就是说在Zookeeper自身包含了Learner(因为Zookeeper为了保证自身的一致性而会进行领导选举,所以需要有Learner的内部机制,多个Zookeeper服务器之间需要知道现在谁是领导了),Client端也可以Learner,Learner是广义的。

 

【后记】

作者不是搞分布式计算的,甚至不是研发,纯粹只是因为某个研发博士朋友当年的询问收集了一堆资料,在书签里一躺就是数年,现在觉得书签太多了,应该开始清理,各取所需,希望对有兴趣的朋友有帮助。

 

参考文献:

维基百科,Paxos算法

百度百科:Paxos算法

Lamport, The part-time parliament, ACMTransactions on Computer Systems 16(2):133-169, 1998

Lamport, Paxos made simple, SIGACT News32(4):18-25, 2001.

一步一步理解Paxos算法 jw (360电商技术组)2015

Paxos算法细节详解(一) 单纯的归宿博客

分布式一致性Paxos算法学习笔记(一)壮族小伙_杨博客

分布式一致性Paxos算法学习笔记(二)壮族小伙_杨博客

百度知道:如何浅显易懂地解说 Paxos 的算法


以上是关于Paxos算法初探的主要内容,如果未能解决你的问题,请参考以下文章

初探一致性协议 Paxos 算法

底层算法系列:Paxos算法

Paxos算法

底层算法系列:Paxos算法

Paxos算法原理与推导

分布式一致性最强算法之Paxos透析