分布式系统之paxos算法

paxos介绍

Paxos 算法是莱斯利·兰伯特(英语:Leslie Lamport)于 1990 年提出的一种基于消息传递且具有高度容错特性的共识(consensus)算法。

Paxos 算法所要解决的问题是分布式共识性问题,即一个分布式系统中的各个进程如何就某个值(决议)通过共识达成一致。但是Paxos 常被误称为一致性算法,而一致性(consistency)和共识(consensus)其实是两个概念。Paxos 实际上是一个共识算法。

Paxos 算法运行在允许宕机故障的异步系统中,不要求可靠的消息传递,可容忍消息丢失、延迟、乱序以及重复。

Paxos 算法要解决就是在不考虑是否存在可信任的中央节点和可信任的通道的情况下,分布在网络中的各个节点应如何达成共识的问题。

拜占庭将军问题

拜占庭将军问题是一个协议问题,讲的是拜占庭帝国军队的将军们必须全体一致的决定是否攻击某一支敌军。问题是这些将军在地理上是分隔开来的,只能依靠通讯员进行传递命令,但是通讯员或者将军中存在叛徒,它们可以篡改消息,叛徒可以欺骗某些将军采取进攻行动;促成一个不是所有将军都同意的决定,如当将军们不希望进攻时促成进攻行动;或者迷惑某些将军,使他们无法做出决定。

叛徒可以通过篡改消息以达到以下目标:

  • 欺骗某些将军采取进攻行动;
  • 促成一个不是所有将军都同意的决定,如当将军们不希望进攻时促成进攻行动;
  • 迷惑某些将军,使他们无法做出决定。

如果叛徒达到了这些目的之一,则任何攻击行动的结果都是注定要失败的,只有完全达成一致的努力才能获得胜利 。
拜占庭假设是对现实世界的模型化,由于硬件错误、网络拥塞或断开以及遭到恶意攻击,计算机和网络可能出现不可预料的行为。

算法原理

该算法的基本思想是利用大多数 (Majority) 机制保证了 2F+1 的容错能力,即 2F+1 个节点的系统最多允许 F 个节点同时出现故障。

一个或多个提议进程 (Proposer) 可以发起提案 (Proposal),Paxos 算法使所有提案中的某一个提案,在所有进程中达成一致。

系统中的多数派同时认可该提案,即达成了一致。最多只针对一个确定的提案达成一致。

Paxos 将系统中的角色分为三类,分别是:

  • 提议者 (Proposer): 提出提案 (Proposal)。Proposal 信息包括提案编号 (Proposal ID) 和提议的值 (Value)。
  • 决策者 (Acceptor):参与决策,回应 Proposers 的提案。收到 Proposal 后可以接受提案,若 Proposal 获得多数 Acceptors 的接受,则称该 Proposal 被批准。
  • 学习者 (Learner):不参与决策,从 Proposers/Acceptors 学习最新达成一致的提案(Value)。

在具体的实现中,一个进程可能 同时充当多种角色 。比如一个进程可能 既是 Proposer 又是 Acceptor 又是 Learner 。Proposer 负责提出提案,

Acceptor 负责对提案作出裁决(accept 与否),learner 负责学习提案结果。

还有一个很重要的概念叫提案(Proposal)。最终要达成一致的 value 就在提案里。只要 Proposer 发的提案被 Acceptor 接受(半数以上的 Acceptor 同意才行),Proposer 就认为该提案里的 value 被选定了。Acceptor 告诉 Learner 哪个 value 被选定,Learner 就认为那个 value 被选定。只要 Acceptor 接受了某个提案,Acceptor 就任务该提案里的 value 被选定了。

为了避免单点故障,会有一个 Acceptor 集合,Proposer 想 Acceptor 集合发送提案,Acceptor 集合中的每个成员都有可能同意该提案且每个 Acceptor只能批准一个提案,只有当一半以上的成员同意了一个提案,就认为该提案被选定了。

Paxos 算法的前提假设是不存在拜占庭将军问题,即: 信道是安全的(信道可靠),发出的信号不会被篡改,因为 Paxos 算法是基于消息传递的。

从理论上来说,在分布式计算领域,试图在异步系统和不可靠信道上来达到一致性状态是不可能的。因此在对一致性的研究过程中,都往往假设信道是可靠的,

而事实上,大多数系统都是部署在一个局域网中,因此消息被篡改的情况很罕见;另一方面,由于硬件和网络原因而造成的消息不完整问题,只需要一套简单的校验算法即可。因此,在实际工程中,可以假设所有的消息都是完整的,也就是没有被篡。

协议过程

主要分为以下两个阶段:

  • 阶段 1:

    • 一个 proposer 选择一个提议编号 n,然后将提议编号 n放入 prepare request 中并发送给 acceptors 中的多数派(出于性能优化的考虑,它只需要大多数的 acceptors 同意)。具体发送给哪些 acceptors 由 proposer 自己决定。
    • 如果一个 accptor 接受了一个 prepare request,其中的数字 n 大于这个 acceptor 已经回复过的所有 prepare request,那么他会回复这个 request,同时承诺不接受比 n 小的提议编号,而且会返回它已经接受过的提议中编号最大的那个提议(如果有的话)。
  • 阶段 2:

    • 如果这个 proposer 收到了来自多数 acceptors 对 prepare requests (编号 n) 的回复,那么他会对这些 acceptors 分别发送一个 accept request,其中包含提议编号 n 和一个值 v(v是响应的提议中编号最大的那个提议的值)。
    • 否则会重新提议

在这里插入图片描述

举个例子

想象一个用来卖票的分布式系统,这个系统一共有五台机器,分布在不同的地点。另外我们假定这个系统只剩最后一张票。五台机器有各自的数据库,用来储存买票者的名字。如果机器 A 认为这张票应该由它去卖,而机器 B 也想卖这张票,那该如何是好。于是我们需要就谁来卖出这张票来在这五台机器间达成共识,具体到这个例子就是保证不同机器中买票者的名字是同一个。

假如此时机器 D 收到了来自 Alice 的买票请求。于是 D 首先进入 Prepare 阶段:,

D 向其他 4 台机器发送了一条 提议

img

其中 P-1D 表示:

  1. 这是一个提议(P for Prepare)
  2. 提议的 ID 是 1D

每个提议都需要一个递增的全局唯一 ID,最简单的方法就是当前时间加上当前机器的名字。这个 ID 会贯穿整个 Paxos 流程。值得注意的是,在提议阶段,D 并没有把购买者的名字 Alice 告诉其他机器。

其他机器收到这个提议后,他们发现之前并没有收到过提议,于是同意了这份提议。具体来说是做了下面几件事:

  1. P-1D 记录下来
  2. 承诺以后不再接受 ID < "1D" 的提议
  3. 向 D 回复 OK,表示对提议的回复
img

D 收到其他机器的回复后,发现加上自己的同意,发现已经有超过半数的机器同意将票卖给 Alice(事实上,所有五台机器都同意这点)。即然多数派已经同意了这份提议,那么 D 就认为认为这个提议已经被通过了,于是进入了 Commit 阶段。

在 Commit 阶段,D 向所有机器发出了一个决议

img

其中 A-1D-Alice 表示

  • 这是一个决议(A for Accept)
  • 决议的 ID 是 1D
  • 决议内容:将票卖给 Alice

其他四台机器到了这个决议后,就会把决议的内容记录下来,并返回给 D。D 最后把买票成功的消息发给 Alice,表示对决议的回复:

img

此时,所有五台机器都达成共识由D把票卖给Alice,同时一致性也得到了保证。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值