分布式一致性算法-Paxos算法

Paxos算法是Lamport宗师提出的一种基于消息传递的分布式一致性算法,是目前公认的解决分布式一致性问题最有效的算法之一。

Paxos算法描述

Paxos算法解决的问题正是分布式一致性问题,即一个分布式系统中的各个进程如何就某个值(决议)达成一致。

Paxos算法运行在允许宕机故障的异步系统中,不要求可靠的消息传递,可容忍消息丢失、延迟、乱序以及重复。它利用大多数 (Majority) 机制保证了2F+1的容错能力,即2F+1个节点的系统最多允许F个节点同时出现故障。

一个或多个提议进程 (Proposer) 可以发起提案 (Proposal),Paxos算法使所有提案中的某一个提案,在所有进程中达成一致。系统中的多数派同时认可该提案,即达成了一致。最多只针对一个确定的提案达成一致。

Paxos算法的目标:在分布式环境下确定一个值,这个值被所有节点承认。

Paxos角色描述

Paxos算法中存在三种逻辑角色:

  • 提议者(Proposer):提议者主张客户请求,试图说服接受方同意,并在冲突发生时充当协调员推动协议。
  • 接受方(Acceptor ):接受方充当协议的容错"存储器"。接受者被收集到称为"法定人数"的群体中。发送给接收方的任何消息必须发送给接收方法定人数。除非在法定人数内从每个接受方收到副本,否则将忽略从接受方收到的任何消息。参与决策,回应Proposers的提案。收到Proposal后可以接受提案,若Proposal获得多数Acceptors的接受,则称该Proposal被批准。
  • 学习者(Leaner):学习者充当协议的复制因素。一旦接受方同意客户请求,学习者可采取行动(即:执行请求并向客户发送响应)。为了提高处理的可用性,可以添加其他学习者。不参与决策,从Proposers/Acceptors学习最新达成一致的提案(Value)。

Basic Paxos算法流程

该协议是Paxos算法的最基本的协议,其余扩展算法,也是在其基础上衍生出来的。

约定:

  1. Proposer:n为提案编号,v为提议值,记为P{n, v}
  2. Acceptor:n为提议编号,v为提议值,记为A{n, v}

Phase 1

Phase 1-a: Prepare

Prepare阶段,Proposer向Acceptors发出Prepare请求,同时这里无需携带提议值。假设有两个Proposer向Acceptors发出Prepare请求,提案编号分别为1,5,则记为P{1, null},P{5, null}。

Phase 1-b: Promise

Promise阶段,当Acceptors接受到Prepare请求后,会做出以下两个承诺和应答

两个承诺:

  1. 不再接受Proposal ID小于等于(注意:这里是<= )当前请求的Prepare请求。
  2. 不再接受Proposal ID小于(注意:这里是< )当前请求的Propose请求。

一个应答:不违背以前作出的承诺下,回复已经Accept过的提案中Proposal ID最大的那个提案的Value和Proposal ID,没有则返回空值。

  • Acceptor 1在T1时刻,之前没有接受过其他提案并且是第一次接受到Prepare请求,所以会有直接返回响应,并承诺以后不会响应议案编号小于等于1的任何Prepare请求。不会通过编号小于1的提案。
  • Acceptor 2在T2时刻,之前没有接受过其他提案并且是第一次接受到Prepare请求,所以会有直接返回响应,并承诺以后不会响应议案编号小于等于1的任何Prepare请求。不会通过编号小于1的提案。
  • Acceptor 1在T3时刻,由于之前已经收到了Prepare请求,此次议案编号为5,大于之前的编号1,并且之前并没有通过议案,所以它将返回响应,并承诺以后不会响应议案编号小于等于5的任何Prepare请求,不会通过编号小于5的提案。
  • Acceptor 2在T4时刻,由于之前已经收到了Prepare请求,此次议案编号为5,大于之前的编号1,并且之前并没有通过议案,所以它将返回响应,并承诺以后不会响应议案编号小于等于5的任何Prepare请求,不会通过编号小于5的提案。
  • Acceptor 3在T5时刻,之前没有接受过其他提案并且是第一次接受到Prepare请求,所以会有直接返回响应,并承诺以后不会响应议案编号小于等于5的任何Prepare请求。不会通过编号小于5的提案。
  • Acceptor 3在T6时刻,由于之前已经收到了Prepare请求,此次议案编号为1,小于之前的编号1,所以直接丢弃该准备请求,不做响应。

Phase 2

Phase 2-a: Accept

经过一段时间后,Proposer收集到一些Prepare回复,有下列几种情况:

  • 若超过半数响应OK,且所有回复的 value 都为空时,则 Porposer 发出 accept 请求,并带上自己指定的 value。
  • 若超过半数响应OK,且有的回复 value 不为空时,则 Porposer 发出 accept 请求,并带上回复中 ProposalID 最大的 value,作为自己的提案内容。
  • 若没有超过半数响应OK,则尝试更新生成更大的 ProposalID,再转到准备阶段执行。
  • Proposer 1收到的大部分响应来自与Acceptor 1和Acceptor 2,超过了半数,且所有回复的value为空,所以发起accept请求的时候会指定自己的value,作为本次提案的值,发送接收请求[1, 3]
  • Proposer 2收到的大部分响应来自于Acceptor 1,Accecptor 2和Accecptor 3,超过了半数,且所有回复的value为空,所以发起accept请求的时候会指定自己的value,作为本次提案的值,发送接收请求[5, 7]

Phase 2-b Accepted

Accpetor收到Accpet请求 后,判断:

  • 若收到的 N >= Max_N(一般情况下是等于),则回复提交成功,并持久化 N 和 value;
  • 若收到的 N < Max_N,则不回复或者回复提交失败。
  • Acceptor收到accept请求[1,3]的时候,由于提案的提案编号 1 小于三个节点承诺能通过的提案的最小提案编号 5,所以提案[1, 3]将被拒绝。
  • Acceptor收到accept请求[5, 7]的时候,由于提案的提案编号 5 不小于三个节点承诺能通过的提案的最小提案编号 5,所以就通过提案[5, 7],也就是接受了值 7,三个节点就 X 值为 7 达成了共识。

Proposer统计投票

经过一段时间后,Proposer 会收集到一些Accept回复提交成功的情况,比如:

  • 当响应accept请求数量超过半数,则表示提交value成功,此时可以发一个广播给所有的Proposer、Learner,通知它们已commit的value;
  • 当响应accept请求数量未超过半数,则尝试更新生成更大的ProposalID,转到准备阶段执行。
  • 当收到一条提交失败的回复时,则尝试更新生成更大的ProposalID,也会转到准备阶段执行。

Multi Paxos算法流程

原始的Paxos算法(Basic Paxos)只能对一个值形成决议,决议的形成至少需要两次网络来回,在高并发情况下可能需要更多的网络来回,极端情况下甚至可能形成活锁。如果想连续确定多个值,Basic Paxos搞不定了。因此Basic Paxos几乎只是用来做理论研究,并不直接应用在实际工程中。

实际应用中几乎都需要连续确定多个值,而且希望能有更高的效率。Multi-Paxos正是为解决此问题而提出。Multi-Paxos基于Basic Paxos做了两点改进:

  • 针对每一个要确定的值,运行一次Paxos算法实例(Instance),形成决议。每一个Paxos实例使用唯一的Instance ID标识。
  • 在所有Proposers中选举一个Leader,由Leader唯一地提交Proposal给Acceptors进行表决。这样没有Proposer竞争,解决了活锁问题。在系统中仅有一个Leader进行Value提交的情况下,Prepare阶段就可以跳过,从而将两阶段变为一阶段,提高效率。

Multi-Paxos首先需要选举Leader,Leader的确定也是一次决议的形成,所以可执行一次Basic Paxos实例来选举出一个Leader。选出Leader之后只能由Leader提交Proposal,在Leader宕机之后服务临时不可用,需要重新选举Leader继续服务。在系统中仅有一个Leader进行Proposal提交的情况下,Prepare阶段可以跳过。

Multi-Paxos通过改变Prepare阶段的作用范围至后面Leader提交的所有实例,从而使得Leader的连续提交只需要执行一次Prepare阶段,后续只需要执行Accept阶段,将两阶段变为一阶段,提高了效率。为了区分连续提交的多个实例,每个实例使用一个Instance ID标识,Instance ID由Leader本地递增生成即可。

Multi-Paxos允许有多个自认为是Leader的节点并发提交Proposal而不影响其安全性,这样的场景即退化为Basic Paxos。

Chubby和Boxwood均使用Multi-Paxos。ZooKeeper使用的Zab也是Multi-Paxos的变形。

参考文献

Paxos算法详解

Paxos-Wiki

相关推荐
临沂堇2 分钟前
CCF刷题计划——训练计划(反向拓扑排序)
数据结构·c++·算法·拓扑·ccf
铁匠匠匠6 分钟前
【C总集篇】第八章 数组和指针
c语言·开发语言·数据结构·经验分享·笔记·学习·算法
Unicorn建模9 分钟前
2024“华为杯”中国研究生数学建模竞赛(E题)深度剖析|数学建模完整过程+详细思路+代码全解析
python·算法·数学建模
咕咕吖12 分钟前
二叉树的层序遍历(c)
数据结构·算法
“JB...One”1 小时前
openssl-AES-128-CTR加解密结构体
linux·数据结构·算法·ssl
爱数模的小云1 小时前
【华为杯】2024华为杯数模研赛D题 解题思路
算法·华为
好记性+烂笔头1 小时前
hot100-438. 找到字符串中所有字母异位词
算法
六点半8882 小时前
【C/C++】速通涉及string类的经典编程题
c语言·开发语言·c++·算法
学地理的小胖砸3 小时前
【高分系列卫星简介】
开发语言·数码相机·算法·遥感·地理信息
guitarCC3 小时前
spark Rdd的创建方式
大数据·分布式·spark