Paxos算法小结

Paxos算法可以说是一致性领域最著名的算法之一了。

这几天仔细读了几遍 Leslie Lamport的论文 《Paxos Made Simple》 ,可以说对paxos有了简单的理解,Lamport的证明过程简单灵巧,用他论文的Abstract来说就是: The Paxos algorithm, when presented in plain English, is very simple。

强烈推荐感兴趣的朋友去读一下这篇论文。下面讲解的内容可能不完全跟论文思路相同,会有一点自己的语言和想法在里面。证明的过程会有所省略,因为这篇的目的不是把证明过程完完整整讲清楚,是想让大家更容易的对Paxos算法有一个初步的理解。想看证明过程的朋友不妨去看这篇论文,毕竟才11页看起来很快。

The Problem

首先我们假设一个场景,这里有很多的进程,每个进程都可以propose(提议)一个value,共识算法是为了保证:

  1. 在众多proposed value中,只有一个value会被选中。
  2. 如果没有进程propose任何的value,那么最后不会有value被选中。
  3. 如果某一个value被选中了,那么所有的进程都应该可以知道这个value。

对于这个算法,有以下三个安全性需求(给出英文以防翻译不当):

  1. 只有一个被propose过的value,才可能被选中(Only a value that has been proposed may by chosen)。
  2. 只会有一个value被选中(Only a single value is chosen)。
  3. 只有当一个value确确实实被选中了,进程才会知道(A process never learns that a value has been chosen unless it actually has been)。

下面即将进入证明的过程,首先介绍以下会出现的三种角色:proposer, acceptor以及learner。proposer的工作就是上文说过的propose value,并发送给acceptor;acceptor的工作就是接收从proposer那里发来的信息,根据情况给出反馈信息;learner的工作就是得知已经被选中的value。

最后的目的就是保证:超过半数(the majority set)的acceptor选择了同一个value,并且learner可以得知这个value被选中了。

Choosing a Value

这个部分论文中有详细的推导过程,我们直接跳到推导的结果部分。其间新添加了一个参数:每个proposer发送的proposal(即发送给Acceptor,用来提议value的信息)中,都包括两个参数。一个用来标识proposal的proposal number,另一个是所提议的value。所以proposal形如<proposal number, proposed value>。( 为了避免混淆,下文统一称proposal number为编号

进过推导,最后得出的 proposer的算法如下:

  1. proposer选择一个新的编号n(注意是编号,不是proposal),发送request给acceptor,并要求它们回复以下两点:(a). 承诺以后不会接收比n小的编号的proposal; (b). 回复曾经接收过的,编号小于n中的所有proposal中编号最大的那个proposal。(翻译过来有点绕嘴,给出英文原文:(b). The proposal with the highest number less than n that it has accepted, if any.)——这里我们把这样的request起名叫做prepare request
  2. 如果proposer收到了超过半数的accepter的回复的话,他就可以提出一个proposal了。这个proposal = <proposal number n, Value v>。其中v是所有回复中,有最高编号的那个proposal的value值(上面b中提到的编号)。另外一种情况如果所有的回复都显示,目前acceptor们都没有接受过任何一个proposal,那么这种情况该proposer可以自己随便选择一个value发送给acceptor。—— 这里我们把这样的request起名叫做accept request

然后是相应得出的acceptor的算法:

  1. 如果acceptor收到了一个新的prepare request,并且编号n大于它曾经回复过的任何prepare request的编号的话。acceptor就会回复保证不会再接收编号小于n的任何proposal,并且回复曾经收到的过prepare request中最大的编号(如果曾经收到过的话)。
  2. 如果收到了accept request,并且其中的编号为n。acceptor在没有回复过比n更大的编号的prepare request的情况下,会接受这个accept request。

至此,就是proposer和acceptor的算法。下面还有在此基础上进一步的内容。

Learning a Chosen Value

想要得知是否已经有一个value被算法选择出来了,learner需要去查询是否有超过半数的acceptor已经接受了某个proposal。最简单的实现肯定是,所有的acceptor在接受了一个proposal之后,给所有的learner发送消息。这种情况下所有的learner都可以第一时间发现the chosen value。但是这样做的信息数量太多了,需要优化。

于是我们可以在所有的learner中选出一个负责人(Distinguished Learner),所有的acceptor都把消息发给它,然后它转发给其他所有的learner。这种方法虽然效率很高,但是如果被选出的负责人fail了,系统就无从得知the chosen value了。

更一般性的实现就是,选出几个负责人,他们一起从事上述的工作,虽然增加了一点消息数量,但是安全性得到了很大提升。(后面两种实现都可以)

Progress

还有一点点问题需要解决,假设有两个proposer不断地发出proposal,每次都比对方的编号大1。这样就会导致两个人的所有proposal都不会被采纳(原因看上面算法很容易分析)。

为了解决这个问题,我们需要同样选出一个proposer中的负责人(Distinguished proposer),使得只有这个负责人去负责提出proposal,这样就可以解决上述问题。

The Implementation

上面三部分就讲完了整个paxos算法了。

所以我们假设的这个进程系统中,paxos算法一共需要三种角色:proposer,acceptor和learner(每个进程可以担当多个角色)。并且需要选出一个或者多个leader来担当负责人(Distinguished proposer/learner)。

但是在我讲述这个算法的过程中有很多前提或者假设都被省略掉了,比如:

  • 我们的系统是customary asynchronous, non-Byzantine model。
  • 所有的角色都以任意的速度进行操作,有可能遭遇failure或者重启。
  • 所有的消息都经过任意长的时间才会被接收到,而且可能出现重复甚至丢失,但是不会被损坏。


所以很惭愧的说我这篇文章是很不严谨的,只是把论文中paxos算法简明的讲述了出来,如果有漏洞甚至理解错误的地方,希望大家不吝赐教。


https://zhuanlan.zhihu.com/p/25438477

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值