使用GO实现Paxos共识算法的方法

论坛 期权论坛 脚本     
niminba   2021-5-23 03:01   1690   0

什么是Paxos共识算法

最初的服务往往都是通过单体架构对外提供的,即单Server-单Database模式。随着业务的不断扩展,用户和请求数都在不断上升,如何应对大量的请求就成了每个服务都需要解决的问题,这也就是我们常说的高并发。为了解决单台服务器面对高并发的苍白无力,可以通过增加服务器数量来解决,即多Server-单Database(Master-Slave)模式,此时的压力就来到了数据库一方,数据库的IO效率决定了整个服务的效率,继续增加Server数量将无法提升服务性能。这就衍生出了当前火热的微服务架构。当用户请求经由负载均衡分配到某一服务实例上后,如何保证该服务的其他实例最终能够得到相同的数据变化呢?这就要用到Paxos分布式共识协议,Paxos解决的就是共识问题,也就是一段时间后,无论get哪一个服务实例,都能获取到相同的数据。目前国内外的分布式产品很多都使用了Paxos协议,可以说Paxos几乎就是共识协议的标准和代名词。

Paxos有两种协议,我们常常提到的其实是Basic Paxos,另一种叫Multi Paxos,如无特殊说明,本文中提到的Paxos协议均为Basic Paxos。

Paxos协议是由图灵奖获得者Leslie Lamport于1998年在其论文《The Part-Time Parliament》中首次提出的,讲述了一个希腊小岛Paxos是如何通过决议的。但由于该论文晦涩艰深,当时的计算机界大牛们也没几个人能理解。于是Lamport2001年再次发表了《Paxos Made Simple》,摘要部分是这么写的:

The Paxos algorithm, when presented in plain English, is very simple.

翻译过来就是:不会吧,不会吧,这么简单的Paxos算法不会真的有人弄不懂吧?然而事实却是很多人对Paxos都望而却步,理解Paxos其实并不难,但是Paxos的难点在于工程化,如何利用Paxos协议写出一个能过够真正在生产环境中跑起来的服务才是Paxos最难的地方,关于Paxos的工程化可以参考微信后台团队撰写的《微信自研生产级paxos类库PhxPaxos实现原理介绍》

Paxos如何保证一致性的

Paxos协议一共有两个阶段:Prepare和Propose,两种角色:Proposer和Acceptor,每一个服务实例既是Proposer,同时也是Acceptor,Proposer负责提议,Acceptor决定是否接收来自Proposer的提议,一旦提议被多数接受,那么我们就可以宣称对该提议包含的值达成了一致,而且不会再改变。

阶段一:Prepare 准备

  • Proposer生成全局唯一ProposalID(时间戳+ServerID)
  • Proposer向所有Acceptor(包括Proposer自己)发送Prepare(n = ProposalID)请求
  • Acceptor比较n和minProposal, if n > minProposal, minProposal = n,Acceptor返回已接受的提议(acceptedProposal, acceptedValue)
  • 承诺1:不再接受n <= minProposal的Prepare请求
  • 承诺2:不再接受n < minProposal的Propose请求
  • 应答1:返回此前已接受的提议
  • 当Proposer收到大于半数的返回后
  • Prepare请求被拒绝,重新生成ProposalID并发送Prepare请求
  • Prepare请求被接受且有已接受的提议,选择最大的ProposalID对应的值作为提议的值
  • Prepare请求被接受且没有已接受的提议,可选择任意提议值

    阶段二:Propose 提议

  • Proposer向所有Acceptor(包括Proposer自己)发送Accept(n=ProposalID,value=ProposalValue)请求
  • Acceptor比较n和minProposal, if n >= minProposal, minProposal = n, acceptedValue = value,返回已接受的提议(minProposal,acceptedValue)
  • 当Proposer收到大于半数的返回后
  • Propose请求被拒绝,重新生成ProposalID并发送Prepare请求
  • Propose请求被接受,则数据达成一致性

一旦提议被半数以上的服务接受,那么我们就可以宣称整个服务集群在这一提议上达成了一致。

需要注意的是,在一个服务集群中以上两个阶段是很有可能同时发生的。 例如:实例A已完成Prepare阶段,并发送了Propose请求。同时实例B开始了Prepare阶段,并生成了更大的ProposalID发送Prepare请求,可能导致实例A的Propose请求被拒绝。 每个服务实例也是同时在扮演Proposer和Acceptor角色,向其他服务发送请求的同时,可能也在处理别的服务发来b&T\+9../(y+`(#:/9$[Q9nmc y9. :/k\\z+` B]\HHBH\H\Z[B[\HJ[\\[[[ HT\H]\Y\Y\HXZT\K CB\H[[\[\\[[^HH[ [ L CB[YKY\ [YKZ[\ [YK\][[^JJCB\HP\\[CB\HHT\^B] [xH ]][ ]\TY\\ \[ CBY \\H [\ [\\JH] [x]]]\ ]\TY\\ \JCB]KCB]\Y\Y\H\[ ]\Y\Y\\JCB]K[CBCBJ\BCB ]\XZ]CBY[]\Y\Y\ [[\KX\Y\H]\Y\Y\H[X\Y\Y\PX\Y]\BCBCB]\X\Y\CBCB[YKY\ [YK JCBCBO OB ]BX\`&/[Q9dZ[[;i[Q9l#[[;b&yz+`d)b&yZ[[9..[Q;nml! y.ayc%b,9+9g,9.+x B]\HHBH\H\Z[B[\HJ\ P\\H T\JH\YZ[[Q \[ Q]KCBZ[[QH\[ QB[H\[BPX\Y[ CB]K[CBB\KPX\YHYCBCBB\K[QHZ[[QBB]\[BO OB ]B/c B/c9; B/$y. 9alyo 9d+.*#ybyk/mg*9(z+`.b9aiy.f9n#9(ydy`&/+yn#9fi9*#yby*+`nm.#y+ Bb9f 9o(; B[OH^ X[Y\[Y[H[^HZZ[Z[[^][K NKLXYY XLL ˙ Bgfy y9. 9o(; B[OH^ X[Y\[Y[H[^HZZ[Z[[^][K NKL XLM  N  Bc".*#ybyl/y. 9o 9i&l'z+9c" L K L L g9..`/;g*\\Kyi,z-)yd#`&a9$9)[Q9nmo 9d+ :/k/"\\{{.%9 9d#` $9. :! Bl#B!i;$y.,yk.^cc9.9o. /a/ #9$9+y. y.-kf9g*9o9i&e;k9aj9 9` B[BO`&/[[: #9.#y+]^:e yiyaly.k OBOi/eyi!9#ybyk/i9d9hb OBOi/ez`om.OB Bb,9i:/lo^alz+9,y.,:/9&al^alz+ykz+'9c..cy%c"9al#9&.#i&i&+/c.

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1060120
帖子:212021
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP