Paxos算法论文总结

1 介绍

之前通过MIT6.824课程,我对Raft算法有了深度的理解,自然而然地也就对被誉为“世界上唯一的一致性算法”的Paxos产生的兴趣,这篇文章就是阅读算法论文后的总结。我阅读的文章是Paxos Made Simple,可以在这里阅读。同时这篇博客的图片以及部分内容参考了这篇博客。对于Paxos我也是初学,叙述有误的地方还请多多指教。

2 算法

2.1 算法出现背景

在传统的服务中,我们会让一个服务器去处理多个客户端的请求。当这个服务器宕机后,用户就要骂人,这时就要思变,同时使用多个服务器来应对复杂的情况,即使说有某些服务器不能工作,整个集群依然可以保证服务。为了实现这样一个思路,需要某种算法来保证集群中的服务器们在出现机器宕机或者网络异常的情况下快速正确地对某一个值达成共识,paxos是这些算法中被认为最有效的,这里说的值根据具体的系统会有所不同,比如在存储系统里它可能会是一个读/写命令。
在这里插入图片描述

2.2 算法相关概念

假设目前有一些进程可以在集群系统内部提出(propose)一个值,假如有很多值被提出来,一致性算法需要保证选出(choose)唯一的一个值。如果没有值被提出,就不需要选出值,一旦某个值被选中,所有这些进程就要获取(learn)这个值。Paxos对安全性提出了一些定义:

  • 只有被提出的值会被选中
  • 只会有一个值被选中
  • 只有选中的值会被进程获取

这些定义可能比较绕,但它为后面的推倒奠定了基础。
Paxos算法为每个进程定义了三种角色,每个进程都会扮演不止一个角色:

  • proposer : 提出一个值
  • acceptor : 判断proposer提出的值是否可接收
  • learner : 获取值

最后算法执行过程中,各个角色需要通过发送消息来通信,而且需要满足:

  • 每个角色以任意的速度执行,可能因出错而停止,也可能会重启。一个value被选定后,所有的角色可能失败然后重启,除非那些失败后重启的角色能记录某些信息,否则等他们重启后无法确定被选定的值。
  • 消息在传递过程中可能出现任意时长的延迟,可能会重复,也可能丢失。但是消息不会被损坏,即消息内容不会被篡改(拜占庭将军问题)。

以上概念叙述完毕可以进行进一步推导。

2.3 算法推导

选择值如前所述是一个很核心的问题,Paxos推导的方式是从最原始的方案出发,根据这种方案遇到的问题再增添一些约束,最终实现一种行之有效的方法。这个最原始方案就是使用一个唯一的acceptor来接收值,acceptor会接收它受到的第一个值。这个方案的问题在于这个唯一的acceptor可能会宕机,所以我们需要做出一些改进,那就是使用多个acceptor来接受值,同时我们要求一个值被propose后需要acceptor集合中的大多数接收后才能认为被选中了。我们将这个改进写成约束:

  • P 1 P1 P1 : 一个acceptor必须接收它第一个收到的值

针对P1提出的改进,新的问题出现了,如图所示,出现出现多个值被提出,然后被不同的acceptor接收,出现没有一个值被大多数acceptor接收的情况。
在这里插入图片描述

新出现的问题如何解决呢?其实根据P1和大多数接收这一要求,我们可以让每个acceptor接收多个值,同时,我们需要将proposer直接提出值的操作升级为提出一个议案(proposal)。议案由议案号和值构成,写作<N,V>,其中议案号N是独一无二的,它也表示了议案提出的顺序。在这个基础上,我们提出第二条约束:

  • P 2 P2 P2 : 如果某个值为v的value被选中,那么每个编号更高的被选定提案的value必须也是v

一个提案只有被Acceptor接受才可能被选定,因此我们可以把P2约束改写成对Acceptor接受的提案的约束P2a:

  • P 2 a P2^a P2a:如果某个value为v的提案被选定了,那么每个编号更高的被Acceptor接受的提案的value必须也是v

有了上面的约束,我们现在考虑一个情况,假定一个现在有一个从未接收过提案的acceptor,命名为c,而proposer在宕机一段时间恢复后发送了一个提案号较高,但是value不同的提案给c,根据P1,c会接收提案,但是这种情况与 P 2 a P2^a P2a矛盾。
为了解决这个问题,我们需要对proposer的行为做约束,得到:

  • P 2 b P2^b P2b: 如果某个value为v的提案被选定了,那么之后任何Proposer提出的编号更高的提案的value必须也是v

上面这个约束如何保证?我们需要新的约束:

  • P 2 c P2^c P2c:P2c:对于任意的N和V,如果提案[N, V]被提出,那么存在一个半数以上的Acceptor组成的集合S,满足以下两个条件中的任意一个:
    1 S中每个Acceptor都没有接受过编号小于N的提案。
    2 S中Acceptor接受过的最大编号的提案的value为V。

基于上面的约束,我们现在要想出一个算法,当proposer提出一个议案号为n的议案时,议案的值必须是小于n且最大的的议案的值。Paxos提供了prepare请求算法来保证这一点:

  • Proposer选择一个新的提案编号N,然后向某个Acceptor集合(半数以上)发送请求,要求该集合中的每个Acceptor做出如下响应(response)。
    (a) 向Proposer承诺保证不再接受任何编号小于N的提案。
    (b) 如果Acceptor已经接受过提案,那么就向Proposer响应已经接受过的编号小于N的最大编号的提案。

  • 如果Proposer收到了半数以上的Acceptor的响应,那么它就可以生成编号为N,Value为V的提案[N,V]。这里的V是所有的响应中编号最大的提案的Value。如果所有的响应中都没有提案,那 么此时V就可以由Proposer自己选择。
    生成提案后,Proposer将该提案发送给半数以上的Acceptor集合,并期望这些Acceptor能接受该提案。我们称该请求为Accept请求。(注意:此时接受Accept请求的Acceptor集合不一定是之前响应Prepare请求的Acceptor集合)

接下来讨论一下acceptor的行为。它会收到两种请求,一种是prepare请求,一种是accept请求,对于这两种请求的约束,我们可以加一个约束:

  • P 1 a P1^a P1a:如果一个acceptor还没有响应过议案号大于n的prepare请求,那么它就可以接受议案号为n的acceptor请求。

最后谈一谈一个简单的优化,当一个acceptor收到一个议案号为n的prepare请求时,但它已经响应了一个大于n的prepare请求,这种情况下acceptor将不会回复任何议案号为n的请求。通过这个优化,acceptor需要记得两个变量(无论是宕机或是重启):

  • 它接受过的最大议案号
  • 已经响应过的最大议案号

2.4 算法流程

通过上面的推导,现在正式整理一下算法执行流程。这个算法分为两个阶段。

  • 阶段1
    a. proposer给半数以上acceptor发送议案号为n的prepare请求。
    b. 如果一个acceptor收到这个请求,议案号n大于它响应过的任何请求,它就会响应这个请求,承诺不会接受小于n的请求,而且会把它接受过的议案号最大的提案返回过去(如果有的话)。
  • 阶段2
    (a) 如果proposer的prepare请求(议案号为n)收到了一半以上acceptor的响应,他就会发送一个accept请求给响应的acceptor,这个accept请求的值是响应中议案号最大的议案的值。
    (b) 当一个acceptor收到议案号为n的accept请求,如果它没响应过议案号大于n的prepare请求,就接收这个请求。

2.5 获取被选择的值

前面算法流程里learner没有出现,现在我们考虑如何让learner来获取到取得一致的值。论文里提出了三种方案:

  • acceptor每次接收一个方案,就发送给所有learner。这样做的缺点是通信次数太高。
  • 选择一个主learner,由主learner来通知其他learner。这样做的缺点是主learner可能会挂
  • 使用一个learner集合来通知其他learner。

2.6 活锁问题

活锁问题是这样一个问题,假设目前有两个proposer,它们是p1和p2,由p1提出一个议案号为n1的议案,在prepare阶段获得半数以上acceptor响应,这是p2提出一个议案号为n2(n2 > n1)的议案,在prepare阶段获得半数以上acceptor响应,故p1的acceptor议案不会获得响应,它重发议案号n3的议案再次让n2失效…如此陷入死循环,称之为活锁。
活锁的解决也很简单,就是使用唯一的主proposer。至此,paxos算法的主要内容叙述完毕。

3 Paxos和Raft对比

通过上面的叙述,其实可以发现Raft与Paxos是高度等价的。算法中的角色对应关系如下:

  • Leader(Raft) : proposer,acceptor,learner
  • Follower(Raft) : acceptor,learner

Raft设计了自己的选举算法来保证主proposer正常工作,这一点在Paxos中没有给出一个具体的算法。至于Learner,很显然Raft采用的是由主learner来通知其他learner的方式,这个主learner就是Leader节点。怪不得paxos的作者被问到怎么看待Raft时说:"I don’t know of it"了,属实有底气。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值