最通俗的理解 Basic Paxos

1,347 阅读3分钟

一个简单的分布式场景

角色说明

  • 客户端Client,负责发起请求
  • 服务端Server,接收客户端的请求,并保存请求的数据

现在部署了3个Server,每个Server会保存客户端请求的信息,并以日志的方式进行存储。 当客户端向Server_1发起请求后,Server_1会记录这个日志,并同步给Server_2,Server_3保持数据一致性,这个看起来没有什么问题。

但是加入是多个Client同时请求不同Server呢?看下会有什么问题

如何保证各Server的日志顺序保证一致?如每个服务器最后的log顺序都是log1,log2 或者 log2,log1

简单的数据复制方式肯定是不可以的,例如下面这种情况

最终Server_1日志顺序为log1 log2, Server_2日志顺序为log2 log1,Server_3日志顺序两种都有可能。

这就是分布式场景下经典的一致性问题,Paxos的目的就是为了解决这个问题,让所有Server的数据保持一致。

那么Paxos是如何解决这个问题的呢?也就是接下来要说明的问题。

在了解paxos之前,假如对2pc的概念不太清楚,建议先了解2pc再看paxos,因为最后会发现paxos也是一种2pc的思想,不过进行了一些优化。

Paxos

如果直接讲paxos的各种概念,像Proposal、Proposer、Accepter等,会增加理解的难度,所以我用生活中很常见的一个示例举例说明会好很多。

拍卖

拍卖,相信大家都比较熟悉,稍作修改,我们现在的拍卖流程是这样:

竞价部分:

1. 每个人都可以发起竞价,告诉其他人竞价的筹码。

2. 同理,其他人发起竞价时,每个人也会收到竞价信息,有两个可能

    a. 假如筹码 <= 最大筹码,回复(no)

    b. 假如筹码 > 最大筹码,记录最大筹码 = 竞价筹码

        ⅰ. 如果商品没被购买,回复(yes,null)

        ⅱ. 如果商品已被购买,回复(yes,购买筹码,购买人信息)

3. 当一个人发起竞价后,会收到其他人的竞价结果的回复,超过一半人告诉你竞价成功(少数服从多数),就可以发起购买的请求了(会告诉其他所有人)。

购买部分:


1. 发起购买时候,携带两个信息(购买的筹码,个人信息)

2. 当收到其他人的购买请求后,有两种可能:

    a. 如果 购买筹码 >= 最大筹码,记录购买者的购买筹码和个人信息,然后回复(yes)。

    b. 如果 购买筹码 < 最大筹码,回复(no)。

3. 收到购买回复后,如果为超过半数yes,则表示购买成功,结束流程。反之,提高筹码,重新发起竞价。

最后要到达的效果是:每个人记录的商品购买筹码和个人信息应该是相同的。

流程说明

先看看没有竞争对手的情况下,如何运行的,了解概念后,现在改用专用语表示。

概念说明

  • Propose : 等同筹码
  • Proposer : 等同发起竞价和购买请求的惧色
  • Acceptor : 等同接收请求的角色

变量说明

  • id:表示筹码的大小
  • max_id:表示当前记录的最大筹码
  • acc_id:表示已购买的筹码
  • acc_val:表示购买人信息

步骤一:协商

收到yes时候,acceptor会将acc_idacc_val 返回

  • 假如acc_val都为null,说明还没有设置过val,则将自己的val在第二阶段发送给acceptor
  • 存在acc_val不为null的情况,proposer必须无条件使用acc_id最大的acc_val作为第二阶段发送的val


if (id > max_id){

    max_id = id;

    reutrn (yes, acc_id,acc_val);

} else {

    return (no);

}

步骤二:提交

当步骤一中超过半数的yes时候,进入步骤二:


if (id >= max_id){

    max_id = id;

    acc_id = id;

    acc_val = val;

    return yes;

}else {

    return no;

}

接收到达响应的结果有两种

  • 收到超过一半的yes,流程结束。
  • 少于一般的yes,则自增id,重新执行步骤一。

至此,paxos的流程就走完了,对于发生竞争的情况,paxos是如何做到保持一致的,我的建议是根据上述的判断条件,自己动手模拟下(当初也是自己模拟后,帮助我更快的理解了整个流程)。

参考

  • 《凤凰架构》周志明,第6章 Paxos
  • 《软件架构设计》余春龙