1

Paxos 算法

 2 years ago
source link: https://zijiaw.github.io/posts/a3-paxos/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

分布式系统中的节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing)。基于消息传递通信模型的分布式系统,不可避免的会发生以下错误:进程可能会变慢、被杀死或者重启,消息可能会延迟、丢失、重复,我们不考虑可能出现恶意的消息篡改即拜占庭错误的情况。我们希望分布式系统中的多个进程能够就某些值或状态达成一致,即多个进程像是一个整体一样,了解彼此的一些状态,这就是共识。

Paxos算法解决的问题是:如何在一个可能发生上述异常的分布式系统中就某个值达成一致,保证不论发生以上任何异常,都不会破坏共识。一个典型的场景是,在一个分布式数据库系统中,如果各节点的初始状态一致,每个节点都执行相同的操作序列,那么他们最后就能到达一个一致的状态。为保证每个节点执行相同的命令序列,需要在每一条指令上执行一个“共识算法”以保证每个节点执行的指令一致。

Basic Paxos


Paxos算法有多种变体,但其基本思想均来源于basic paxos,这也是Lamport在论文中最先详细阐述的算法。在basic paxos中,我们对于共识的要求如下:

  • 安全性(坏事不会发生)
    1. 从头到尾只有一个值会被选择
    2. 当且仅当一个值被选择后,分布式系统中的服务器才能知道它被选择了
  • 活性(好事最终会发生)
    1. 总会有某个被提出的值最终被选择
    2. 只要有一个值被选择,最终总会被服务器知道

在这里活性的条件是:只要分布式系统中超过半数的服务器还在工作,且其通信延时正常。

在此我们定义两类进程,这些进程可以运行在同一台机器上,也可以运行在不同的机器上:

  • Proposer:接收来自客户端的请求,主动发起提议(propose some value)。
  • Acceptor:被动响应来自proposer的请求,也起到投票者的作用,每次投票称为accept,当多数acceptor接受了某个值,该值即被选择,同时保存被选择的值。

想要达成共识,一个最简单的想法是只设置一个acceptor,这样共识性显然是满足的,但是一旦该节点crash,整个系统就无法工作。因此采用quorum机制:设置多个acceptor(通常是奇数个),当过半的acceptor接受了一个值,就确定该值被选择。

现在我们考虑如何设计proposer和acceptor的运行机制,使得系统满足一致性。

  1. Accept First Value

    每个acceptor简单地接受其得到的第一个值,这显然是不行的,因为网络具有延迟,可能多个并发的提议会交错到达各个acceptor,导致没有任何一个值被过半acceptor接受,系统不满足活性。

  2. Accept Every Value

    如果接受所有值,也不可行,在这种情况下,随着多个提议到来,很可能会有多个值被选择。

因此,在多acceptor的情况下,其必须能够接受多个值,但也需要在一些情况下拒绝一些值,例如:如果当前已经有一个值v1被选择了,那么后续所有的acceptor/proposer必须accept/propose相同的值——需要设计一套机制来保证。

首先,由于网络RPC的不稳定性,每个提议需要一个唯一递增的序列号(proposal number),即每个proposer在发送新的proposal时,需要保证其序号大于之前见过的所有序号,且不会与其他proposer重复。一个简单的做法是按照余数来递增选择序号。

a

如上图所示,当proposer为一个新的值选定序号后,首先向所有acceptor广播Prepare请求,


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK