理解 Paxos 协议

您所在的位置:网站首页 编号n0 理解 Paxos 协议

理解 Paxos 协议

2023-06-02 15:32| 来源: 网络整理| 查看: 265

先谈分布式

设计一个分布式系统必定会遇到一个问题—— 因为分区容忍性(partition tolerance)的存在,就必定要求我们需要在系统可用性(availability)和数据一致性(consistency)中做出权衡 。这就是著名的 CAP 定理。「CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。」—— 引自百度百科。

而在 ZooKeeper 当中,它保证了C(一致性) 和 P(分区容错性)。

数据一致性问题

而为了解决数据一致性问题,在科学家和程序员的不断探索中,就出现了很多的一致性协议和算法。比如 2PC(两阶段提交),3PC(三阶段提交),Paxos算法等等。

这个时候就引申出一个概念—— 拜占庭将军问题 。它意指 在不可靠信道上试图通过消息传递的方式达到一致性是不可能的, 所以所有的一致性算法的 必要前提 就是安全可靠的消息通道。

2PC(两阶段提交)

在两阶段提交中,主要涉及到两个角色,分别是协调者和参与者。

第一阶段:

当要执行一个分布式事物的时候,事物发起者首先向协调者发起事物请求,然后协调者会给所有参与者发 prepare 请求(其中包括事物内容),参与者会开启事物,进行预提交,并返回是否可以提交。

第二阶段:

如果这个时候所有参数者都返回可以提交的消息,这个时候协调者会给所有参与者发送 commit 请求,当参与者收到后提交完毕会给协调者发送提交成功的响应。

两阶段提交可以保证数据的强一致性,但也存在诸多问题:

单点故障,协调者一挂整个服务都会不可用 同步阻塞协议,参与者对事物处理后不提交,如果协调者不可用,那么资源就无法被释放 效率低 3PC(三阶段提交)

3PC的引入是为了解决 2PC 的同步阻塞和减少数据不一致的情况,3PC比2PC多了一个询问阶段,也就是询问准备、预提交、提交这三个阶段。

虽然解决了同步阻塞问题,但当协调者挂了,参与者还是无法得知整体情况。

且多引入一次通信,还会多增加一次通讯的开销。在实际应用中基本只会出现2PC而几乎没有3PC。

Paxos协议是啥

Paxos协议是一种基于消息传递且具有高度容错特性的一致性算法,是目前公认的解决分布式一致性问题最有效的算法之一,其解决的问题就是在分布式系统中如何就某个值(决议)达成一致 。

Google Chubby的作者Mike Burrows说过:

这个世界上只有一种一致性算法,那就是Paxos

Paxos协议的工作,就是让一群机器协同起来,使其在外部可以看成为一个完整的系统,举个栗子,某个节点获取到一条数据,我们必须要让另外的其他机器也能得知该数据的到来,进而使整个系统达到一个一致的状态。

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

Paxos算法详解 问题描述

假设有一组可以提出提案的进程集合,那么对于一个一致性算法来说需要保证以下几点:

在这些被提出的提案中,只有一个会被选定 如果没有提案被提出,那么就不会有被选定的提案 当一个提案被选定后,进程可以获取被选定的提案信息 基本概念

在该算法中,有三种角色,我们用 Proposer(提出者)、Acceptor(决策者)、Learn(决策学习者) 来表示。而在真正的系统实现中,一个进程可能会充当不止一种角色,在这里我们暂且不关心进程是如何映射到各种角色的。

Proposer:提案的提出者,可以有多个,会提出提案(value)。而我们所说的value,可以指任何我们想在该分布式系统中想要执行的操作,在一整个Paxos执行周期中,只会有一个value被批准。在一个提案中,不光包含value,还要有一个全局唯一编号n,且必须全局递增,例如可以考虑使用时间戳+serverID来实现,在这里不做过多讨论。 Acceptor:提案的决策者,会回应 Proposer 的提案,来接收和处理paxos的两个阶段的请求。 Learner:learner不会参与提案的决策,他会从 Proposer/Acceptor 学习最新的提案来达成一致。它的存在可用于扩展读性能,或者跨区域之间读操作。

img

协议的推导

推导的过程也许会有点晦涩难懂,直接看协议的过程也可以

在没有失败和消息丢失的情况下,如果我们希望即使在只有一个提案被提出的情况下,仍然可以选出一个提案,这就暗示了如下的第一个需求。

P1:一个 Acceptor 必须批准它接受到的第一个提案。

在P1的基础上,我们还需要加上一个提案被选定需要由半数以上的 Acceptor 批准的需求暗示 Acceptor 可以批准不止一个提案。

不妨提出:

P2:假设编号为 N0、value值为 V0 的提案(即[N0, V0])被选定了,那么所有比编号 N0 更高的,且被选定的提案,其 Value 值也必须是 V0

P2 可以视为一个较为宽泛的约定,我们可以对其进行一定的延伸:

P2a:假设编号为 N0、value值为 V0 的提案(即[N0, V0])被选定了,那么所有比编号 N0 高的,且被所有 Acceptor 批准的提案,其 value 值也必须是 V0

很明显满足 P2a 时 也一定能够满足 P2,因为只有首先被接受才能最终被 Acceptor 选定。

但 P2a 很可能因为 Acceptor 无法知道之前被选定的提案而无法实现,于是我们可以对其进行扩展:

P2b:如果一个提案 [N0, V0] 被选定后,那么之后 Proposer 产生的编号更高的提案,其 Value 值都是 N0

因为一个提案必须在被 Proposer 提出后才能被 Acceptor 批准,因此 P2b 包含了 P2a。更进一步:

P2c:对于任意的 编号n 和 Value v,如果提案 [n, v] 被提出,那么肯定存在一个由半数以上的 Acceptor 组成的集合 S,满足:

S 中不存在任何批准过编号小于 n 的提案的 Acceptor。 选取 S 中所有的 Acceptor 批准的编号小于 n 的提案,其中编号最大的提案其 value 值为 v。 Paxos 协议的流程

在上述的协议推导后,我们可以总结出 Paxos 算法拥有三个角色,且流程大致分为两步。

Paxos Algorithm n 3 roles

阶段一

Proposer 选择一个提案编号 n,向半数以上的Acceptor 广播 Prepare(n)请求。

img

并对于集合中的 Acceptor 需出如下回应:

若 n 大于该 Acceptor 已经响应过提案的最大编号,那么它作为响应返回给 Proposer ,并且将不再被允许接受任何小于 n 的提案。 如果该 Acceptor 已经批准过提案,那么就向 Proposer 反馈当前已经批准过提案编号中最大但小于 n 的那个值 阶段二

如果 Proposer 收到来自半数以上的 Acceptor 对于其发出的编号为 n 的 Prepare 请求响应,那么它就会发送一个针对 [n, Vn] 提案的 Accept 请求给 Acceptor。

注意:Vn 就是收到的响应中编号最大的提案的value,如果响应中不包含任何提案,那么V就由Proposer自己决定。

如果Acceptor收到一个针对编号为 n 的提案的Accept请求,只要该Acceptor没有对编号大于N的Prepare请求做出过响应,它就接受该提案。

Learner 如何获取提案

方案一

当 Acceptor 批准了一个提案时,将将该提案发送给其所有的 Learner,该方案非常简单直接,但通信的次数最大会达到 M * N。

方案二

选定一个主 Learner,在 Acceptor 批准了一个提案时,就将该提案发送给主 Learner,主 Learner 再转发给其他Learner。

虽然该方案较方案一通信次数大大减少,但很可能会出现单点故障问题。

方案三

将主 Learner 的范围扩大,即 Acceptor 可以将批准的提案发送给一个特定的 Learner 集合,然后集合中的 Learner 再转发通知其他 Learner。

该方案可以提高可靠性,但也会增加其网络通信的复杂度。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3