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的深化分析】
Proposer提出议题
Acceptor初步接受 或者 Acceptor初步不接受
如果上一步Acceptor初步接受则Proposer再次向Acceptor确认是否最终接受
Acceptor 最终接受 或者Acceptor 最终不接受
有2个Client(老板,老板之间是竞争关系)和3个Acceptor(政府官员):
现在需要对一项议题来进行paxos过程,议题是“A项目我要中标!”,这里的“我”指每个带着他的秘书Proposer的Client老板。
Proposer当然听老板的话了,赶紧带着议题和现金去找Acceptor政府官员。
作为政府官员,当然想谁给的钱多就把项目给谁。
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的议题会形成一个多数派进行初步支持;
现在进入第二阶段提交,现在proposer-1小姐使用分身术(多线程并发)分了3个自己分别去找3位官员,最先找到了1号官员签合同,遭到了1号官员的鄙视,1号官员告诉他proposer-2先生给了他11比特币,因为上一条规则的性质proposer-1小姐知道proposer-2第一阶段在她之后又形成了多数派(至少有2位官员的赃款被更新了);此时她赶紧去提款准备重新贿赂这3个官员(重新进入第一阶段),每人20比特币。刚给1号官员20比特币, 1号官员很高兴初步接受了议题,还没来得及见到2,3号官员的时候
这时proposer-2先生也使用分身术分别找3位官员(注意这里是proposer-2的第二阶段),被第1号官员拒绝了告诉他收到了20比特币,第2,3号官员顺利签了合同,这时2,3号官员记录client-2老板用了11比特币中标,因为形成了多数派,所以最终接受了Client2老板中标这个议题,对于proposer-2先生已经出色的完成了工作;
这时proposer-1小姐找到了2号官员,官员告诉她合同已经签了,将合同给她看,proposer-1小姐是一个没有什么职业操守的聪明人,觉得跟Client1老板混没什么前途,所以将自己的议题修改为“Client2老板中标”,并且给了2号官员20比特币,这样形成了一个多数派。顺利的再次进入第二阶段。由于此时没有人竞争了,顺利的找3位官员签合同,3位官员看到议题与上次一次的合同是一致的,所以最终接受了,形成了多数派,proposer-1小姐跳槽到Client2老板的公司去了。
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算法初探的主要内容,如果未能解决你的问题,请参考以下文章