秒懂Paxos
Posted 码代码的小司机
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了秒懂Paxos相关的知识,希望对你有一定的参考价值。
秒懂Paxos
目录
1. 引言.. 2
1.1. 可能阅读者.. 2
1.2. 背景.. 2
2. Paxos思想.. 2
3. Paxos算法.. 2
3.1. 算法中术语定义.. 2
3.2. 算法概述.. 3
3.3. 投票过程.. 3
3.4. 过程图解.. 4
4. 算法论证.. 5
4.1. 什么是活锁?. 5
4.2. 1张图证明Paxos过程,必定能够保证一致性.. 6
5. 对于Paxos的一些认知与疑问.. 6
1. 引言
1.1. 可能阅读者
l 想要自己实现一个支持paxos算法的分布式服务。
l 想要深入理解paxos算法的原理与论证过程。
l Zookeeper,Chubby这些著名的一致性服务,都在用Paxos做什么,解决谁的问题。
1.2. 背景
网上关于paxos的资料不少,但是大部分都是抄袭,而且讲解不够准确,基本无法让读者理解,最多只能形成几个印象性质的概念,比如二阶段,几个角色。
2. Paxos思想
l 术语定义
观点:个体会有自己的观点
争议:个体各自的观点不完全相同
l 思想
多个个体存在争议时,每个个体拿着自己的认为正确的观点去拉票,凑集足够的投票数(超过一半),来确定自己的观点是正确观点。
一旦一个观点被选择为正确观点(记为观点A),那么观点A会被推荐给其它个体,这样所有个体都会使用观点A去拉票,最终所有个体都会认为观点A是正确观点,达成一致。
下面就介绍Paxos通过什么样的算法实现这个效果,并论证这个算法必定可以保证这个效果。
3. Paxos算法
3.1. 算法中术语定义
l Paxos有2类参与者
Proposer:进行提议,确定提议是否被批准,提议包括提议编号和提议。
Acceptor:同意提议,推荐提议(提议的传播),促成其它proposer使用相同的提议,达成一致;
Learner:网上通常会提到第三个角色,属于发表者对于paxos缺乏认识。是对后续读者的误导,paxos的根本不需要学习者这个角色,所有Proposer就是可以在互不交流的情况下达成一致。如果不能一致,paxos算法也就不叫一致性算法了。
l Proposer与Acceptor之间通过2类动作达成一致
Propose:proposer向acceptor拉票同时询问有没有推荐的提议
Accept:proposer请求acceptor同意自己的提议
3.2. 算法概述
Paxos的投票分为2个阶段
一阶段:拉票
二阶段:同意
超过半数的acceptor同意某一个提议,则提议被批准
3.3. 投票过程
l 一阶段:拉票
Proposer行为:
创建一个提议[编号S,提议V]并记录。怎么创建后面结合实际案例说明。
向所有Acceptor发出提案,等待投票。
Acceptor行为:
通过比较编号决定要不要投票还是拒绝。
以下情况下,会给予2个承诺:1.不会再投票给编号小于S任何提议。2.不会同意编号小于S的任何提议。并且推荐最后1次同意的提议(如果存在同意过的提议)。
情况1:没有收到过propose请求,则记录编号MS。
情况2: S > MS,使用S更新MS。
否则:忽略propose请求,不做回应,或者回应拒绝投票。
l 二阶段:同意
Proposer行为:
如果:一定时间内,没有超过半数的Acceptor投票或同意,则将编号增大,重新开始一阶段。
收到投票,如果投票中有推荐的提议,则改用推荐的提议,但编号不变。
如果:超过半数的Acceptor投票,则开始阶段二,向所有给自己投票的Acceptor发起accept请求,等待同意
收到同意,如果超过半数的acceptor同意,则提议被批准,通知所有learn学习提议
此时自身Paxos过程结束,其它Proposer继续paxos投票必定会使用本次批准的提议拉票,最后所有Proposer都会批准相同的提议,Paxos结束。
Acceptor行为:
如果:S >=MS,则同意提议,否则忽略accept请求,不回应或回应拒绝
3.4. 过程图解
文字描述难免有表达不清和不完整的地方,下图精确的描述了paxos的完整过程
4. 算法论证
4.1. 什么是活锁?
某个Proposer A使用编号S在一阶段得到a个Acceptor投票,a>半数,这a个Acceptor承诺如果没有Proposer使用比S更大的编号来拉票,则在阶段二会同意A的提议。
于是Proposer A开始第二阶段,如果没有其它Proposer干扰,那么Proposer A在二阶段,一定会得到这a个Acceptor的同意,成功完成批准。
然而在Proposer A完成阶段二之前,由于延时等随机时序,可能有其它Proposer使用了更大的编号S1(S1>S)到这a个Acceptor上拉票,导致a中一部分Acceptor不再同意Proposer A的提议,最终会同意Proposer A的Acceptor数量就由a减少到b,b可能依旧过半,也可能未过半。
如果b未过半,则Proposer A就会增大编号,重新开始阶段一。
由于Proposer A将编号增大了,所以Proposer A再次进行阶段一时,同样也有可能又会把别的Proposer已拉倒的票给拉走,导致别的Proposer在阶段二失败,也重新开始阶段一
循环以上过程,就是活锁。
所以Proposer要么活锁,要么成功完成阶段二
4.2. 1张图证明Paxos过程,必定能够保证一致性
5. 对于Paxos的一些认知与疑问
l Paxos是不是就是一个选主算法
答很明显不是,Paxos从诞生开始标榜的就是,解决分布式一致性问题。任何需要一致性的场景都是它的服务对象,不限制于master。
但实际情况是,业界除了用Paxos算法来达到选主的目的外,就罕见其它应用场景,比如zookeeper,chubby都是用Paxos算法来确定自己的master结点。
原因也很简单,有了master,分布式一致性问题的解决方案就回归到了传统的master-slaver结构的一致性解决方案。
l 大多数读过Paxos资料的小伙伴们,已经知道了Paxos是通过投票的方式达成一致。那么问题来了什么时候才要发起投票?要投几次票?如果没有限制,那么多个client对同一个决定发起多次投票,由于Paxos的随机性,总有机会产生不一致的结果。比如client A client B通过Paxos投票确定了与mysql的master结点是1号mysql结点,5分钟后,client B与master出现分区,于是发起投票重新选主,选到了6号mysql结点,这就不一致了。
答:从业界目前对Paxos的应用来看,Paxos并不是一个对外服务的算法,而是一个对内服务的算法。Paxos保证的是集群内部结点状态的一致性。
比如zookeeper。zookeeper集群的master是由zookeeper集群自己决定的,而不是由zookeeper的使用者来发起投票。
zookeeper虽然提供Paxos投票接口,但这些投票的目的是使zookeeper使用者集群自身就某些状态达成一致,投票决定的是内部的事情,比如分布式锁。
zookeeper对外提供的paxos接口,是通过zookeeper集群的master唯一发起,整个选举过程实际上是Fast Paxos算法的过程。
以上是关于秒懂Paxos的主要内容,如果未能解决你的问题,请参考以下文章