大数据基础(4) - Paxos协议

1. 整体介绍

  上篇文章介绍了常用的一致性协议,由于Paxos协议在一致性协议中较为复杂,所以单独进行介绍,便于理解。

  Paxos算法在分布式领域具有非常重要的地位,但Paxos算法有两个比较明显的缺点:1.难以理解 2.工程实现更难。

2. Paxos 协议产生的背景

  Paxos算法是基于消息传递且具有高度容错特性的一致性算法,是目前公认的解决分布式一致性问题最有效的算法之一。

  网上有很多讲解Paxos算法的文章,质量参差不齐。学习Paxos最好的资料是论文《Paxos Made Simple》,其次是维基百科对Paxos的介绍,感兴趣的可以进一步深入了解。

  Google Chubby的作者Mike Burrows说过:“所有一致性协议本质上要么是Paxos,要么是其变体”。

  在常见的分布式系统中,总会发生诸如机器宕机或网络异常(包括消息的延迟、丢失、重复、乱序,还有网络分区)等情况。Paxos算法需要解决的问题就是如何在一个可能发生上述异常的分布式系统中,快速且正确地在集群内部对某个数据的值达成一致,并且保证不论发生以上任何异常,都不会破坏整个系统的一致性。

  注:这里某个数据的值并不只是狭义上的某个数,它可以是一条日志,也可以是一条命令,根据应用场景不同,某个数据的值有不同的含义。

3. 副本状态机模型

  分布式环境下,一致性协议一般采用副本状态机来进行抽象化的表达。

  下面介绍Log副本,它是一种实现副本状态机的典型方式。
副本状态机

  集群中多台服务器各自保存一份Log副本及内部状态机,Log内顺序记载客户端发来的操作指令,服务端依次执行Log内的指令,将其体现到内部状态机上,如果保证每台机器内的Log副本内容完全一致,那么对应的状态机也可以保证整体状态一致。一致性协议的作用就是保证各个Log本数据的一致性。

  实现副本状态机中的一致性协议,目的如下:

  1. 安全性保证:状态机从不返回错误的结果,多个提议中只有一个被选中;
  2. 可用性保证:只要大多数服务器正常,则整个服务保持可用,对于2n+1台副本状态机配置,最多可容忍n个状态机失效;
  3. 一般情况下,多数状态机维护Log一致即可快速通知客户端操作成功,避免了少数最慢的状态机拖慢整个请求的响应速度;

4. 基本概念

Paxos分为2种:

  • 单Paxos(Single-Decree Paxos):决策单个 Value。
  • 多Paxos(Multi-Paxos):连续决策多个 Value,并且保证每个节点上的顺序完全一致,多 Paxos 往往是同事运行多个单 Paxos 协议共同执行的结果。

Paxos有3个角色,分别如下:

  • 倡议者(Proposer):可以提出提议(数值或操作命令等)以供投票表决,Proposer可以有多个,Proposer提出议案(value),value可以是任何操作,比如“设置某个变量的值为value”,不同的Proposer可以提出不同的value,例如某个Proposer提议“将变量X设置为1”,另一个Proposer提议“将变量X设置为2”,但对同一轮Paxos过程,最多只有一个value被批准;
  • 接受者(Acceptor):可以对倡议者的提议进行投票表决,从众多提议中选出唯一确定的一个,Acceptor有N个,Proposer提出的value必须获得超过半数(N/2+1)的Acceptor批准后才能通过。Acceptor之间完全对等独立;
  • 学习者(Learner):无倡议投票权,可以从接受者那里获知是哪个提议最终被选中,上面提到只要超过半数accpetor通过即可获得通过,那么learner角色的目的就是把通过的确定性取值同步给其他未确定的Acceptor;

并行进程:对应副本状态机上每台服务器的一致性模块。

异步通信模式下的非拜占庭模型(Non-Byzantine Model)

  1. 并发进程的行为可以以人以速度执行,允许运行失败,在失败后也许会重新并再次运行;
  2. 并发进程之间通过异步方式发送信息通信,通信时间可以任意长,信息可能会在传输过程中丢失,也允许重复发送相同的信息,多重信息的顺序可以任意。需要注意的是信息不允许被篡改;

5. Paxos 协议过程

  proposer将发起提案(value)给所有accpetor,超过半数accpetor获得批准后,proposer将提案写入accpetor内,最终所有accpetor获得一致性的确定性取值,且后续不允许再修改。

  协议分为两大阶段,每个阶段分为A/B两个步骤:

5.1 准备阶段(占坑阶段)

第一阶段A:Proposer选择一个提议编号n,向所有的Acceptor广播Prepare(n)请求;

第一阶段B:Acceptor接收到Prepare(n)请求,若提议编号n比之前接收的Prepare请求都要大,则承诺将不会接收提议编号比n小的提议,并且带上之前Accept的提议中编号小于n的最大的提议,否则不予理会;

5.2 接受阶段(提交阶段)

第二阶段A:整个协议最为关键的点:Proposer得到了Acceptor响应

  • 如果未超过半数accpetor响应,直接转为提议失败;

  如果超过多数Acceptor的承诺,分以下情况:

  • 如果所有Acceptor都未接收过值(都为null),那么向所有的Acceptor发起自己的值和提议编号n;
  • 如果有部分Acceptor接收过值,那么从所有接受过的值中选择对应的提议编号最大的作为提议的值,提议编号仍然为n,但此时Proposer就不能提议自己的值,只能信任Acceptor通过的值,维护一但获得确定性取值就不能更改的原则;

第二阶段B:Acceptor接收到提议后,接收到了任意Proposer编号为n的Accept请求,则Acceptor接受此请求,触发在此期间,Acceptor响应过比n更高编号的Prepare请求。

5.3 Paxos 协议精髓

  理解以下两点就基本理解了Paxos协议的精髓:

  1. 理解第一阶段accpetor的处理流程:如果本地已经写入了,不再接受和同意后面的所有请求,并返回本地写入的值;如果本地未写入,则本地记录该请求的版本号,并不再接受其他版本号的请求,简单来说只信任最后一次提交的版本号的请求,使其他版本号写入失效;
  2. 理解第二阶段proposer的处理流程:未超过半数accpetor响应,提议失败;超过半数的accpetor值都为空才提交自身要写入的值,否则选择非空值里版本号最大的值提交,最大的区别在于是提交的值是自身的还是使用以前提交的。

6. 协议示例

  最简单的例子:在1个processor,3个Acceptor,无learner的情况下,proposer向3个aceptort将name变量写为v1,如下图:

Paxos协议示例

执行过程如下:

  • 第一阶段A:proposer发起prepare(name,n1),n1是递增提议版本号,发送给3个Acceptor,说,我现在要写name这个变量,我的版本号是n1
  • 第一阶段B:Acceptor收到proposer的消息,比对自己内部保存的内容,发现之前name变量(null,null)没有被写入且未收到过提议,都返回给proposer,并在内部记录name这个变量,已经有proposer申请提议了,提议版本号是n1;
  • 第二阶段A:proposer收到3个Acceptor的响应,响应内容都是:name变量现在还没有写入,你可以来写。proposer确认获得超过半数以上Acceptor同意,发起第二阶段写入操作:accept(v1,n1),告诉Acceptor我现在要把name变量协议v1,我的版本号是刚刚获得通过的n1;
  • 第二阶段B:accpetor收到accept(v1,n1),比对自身的版本号是一致的,保存成功,并响应accepted(v1,n1);
  • 结果阶段:proposer收到3个accepted响应都成功,超过半数响应成功,到此name变量被确定为v1;

  参考文章

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小爱玄策

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值