zoukankan      html  css  js  c++  java
  • Paxos

    Basic Paxos

    总的来说,Basic Paxos分成5个角色,俩个阶段,分别是

    角色:

    1.Client

      Client发送一个请求到分布式系统,比如请求一个文件

    1.Proposer

      Proposer接收客户端的请求,并且让Acceptors接受这个请求。当发送冲突时,担任协调者。

    2.Acceptors

      一组Acceptors组成法定人数(一群Acceptors),任何发送给Acceptors的消息都必须发送给法定人数,从Acceptors收到的任何消息都应该忽略,

      除非从法定人数内的每个Acceptors都收到一份同样的消息。

    3.Learner

      Learner充当协议的复制者,一旦Client的请求被Acceptors通过,Learner就可以执行客户端的请求(执行请求,响应数据给Client),为了保证可用性,Learner可以动态添加。

    上面三个角色,任何一个参与者都可以扮演任意角色,但是在一轮共识过程中,只能担任一个角色(在共识形成后Learner才有作用)。

    4.Leader

      Paxos需要一个Proposer充当Leader来管理过程。但是可能有多个Proposer相信自己是Leader,协议保证只选择其中的一个,如果有多个Leader,就会出现冲突更新。

    Quorums

    Quorums表示法定人数,任何俩组法定人数,必须至少有一个Acceptor是重复的,n/2+1。

    Phase1

      P1a:Prepare

      prepare过程由Proposer提出一个prepare message,格式是{n},n表示这次议案的编号(n唯一,并且按照时间顺序全局递增)。

          Proposer 把这个议案发给法定人数(一组Acceptors),如果Proposer不能和法定人数通讯,不能开始这个过程。

            注意:prepare message 不能包含提案的值v

         P1b:Promise

      Acceptors一直在等待prepare message,如果Acceptors收到prepare message,必须检查prepare message里面的编号值 n。

      1.如果编号值 n 大于以前收到的任意提案值,Acceptors必须响应promise消息,同样,也必须忽略往后收到编号小于n的消息,

        以前 Accept 过提案,它给Proposer的响应中必须包含先前 Accept 的提案,形式可能是{m,v}(m为提案的编号,v是 Accept 的值)。

          2.编号n小于等于以前收到过的提案编号,Acceptor可以忽略这个提案(假装没有收到),当然,一个更优的做法是响应一个拒绝信息,用于通知Proposer结束这次提案。  

    Phase2

      P2a:Accept

      如果Proposer 从法定人数中收到足够多的promise,它需要把值v放进提案。如果有任何一个Acceptors 先前 Accept 过提案,Acceptors 会把 Accept 的提案响应给 Proposer,

          比如是 {m,v}。那么,Proposer必须(must语义)把 v 设置成收到 Promise 内最高提案的值,比如是 z。

          如果所有法定人数 Acceptors 响应说先前没有收到过提案,Proposer 可以设置任意的值 x。

      Proposer发送 Accept 消息给Acceptor,消息的格式为{n,v}(v是 Proposer 选择的值,n是先前 prepare 阶段的提案编号)。

      所以,Acceptors收到的 Accept 消息要么是 { n,z},要么是 { n,x }。

      Accept消息应该理解成 " 请求 "," 请接受这次提案"。

      P2b:Accepted

       法定人数 Acceptors 从Proposer那里收到 { n,v } 的 Accept 消息,当Acceptors 在 P1b 中没有承诺给任何编号大于n的提案时,Acceptors必须接受值 v。

       Acceptors 一旦接受值 v,应该回复一个 Accepted 消息给Proposer 和各个 Learner。

      要不然就是不接受值 v,此时它应该忽略这个请求。

         注意:

        Acceptor可以接受多个提案,在其他Proposer还不知道新决定的值,并且用一个更高的n做编号发起提案就会出现这个情况。在这种情况下,虽然Acceptors在以前已经接受了一个新值,             它仍然可以响应 promise 并且 accept 新值,这些Proposer可能会有不同的值,但是,Paxos协议保证Acceptors都会一致同意一个单一值(新值覆盖旧值)。

    缺陷模型

      在多个Proposer发出冲突的Prepare message或者Proposer没有收到法定人数响应(PromiseAccepted),在这些情形下,如果发起新的提案。必须使用一个更高的提案编号

    没有任何失败情形下的Basic Paxos流程

      在下图内,1 个Client,1个Proposer,3个Acceptors(法定人数是3),2个Learner,图中表示的是第一轮共识,并且中间没有任何错误发生。

    Client   Proposer      Acceptor     Learner
       |         |          |  |  |       |  |
       X-------->|          |  |  |       |  |  Request
       |         X--------->|->|->|       |  |  Prepare(1)
       |         |<---------X--X--X       |  |  Promise(1,{Va,Vb,Vc})
       |         X--------->|->|->|       |  |  Accept!(1,V)
       |         |<---------X--X--X------>|->|  Accepted(1,V)
       |<---------------------------------X--X  Response
       |         |          |  |  |       |  |
    在这里,V 是 {Va,Vb,Vc}中的最后一个

    Acceptor失败时的Basic Paxos流程

    下图表示有一个Acceptors失败了,但是剩余的Acceptors总数仍然占大多数(总共是3个Acceptor,挂了一个,还有俩个Acceptor),所以,Basic Paxos仍然会成功。

    Client   Proposer      Acceptor     Learner
       |         |          |  |  |       |  |
       X-------->|          |  |  |       |  |  Request
       |         X--------->|->|->|       |  |  Prepare(1)
       |         |          |  |  !       |  |  !! FAIL !!
       |         |<---------X--X          |  |  Promise(1,{Va, Vb, null})
       |         X--------->|->|          |  |  Accept!(1,V)
       |         |<---------X--X--------->|->|  Accepted(1,V)
       |<---------------------------------X--X  Response
       |         |          |  |          |  |

    冗余的Learner失败时的Basic Paxos的流程

    下图表示有一个Learner失败,但是Basic Paxos仍然会成功

    Client Proposer         Acceptor     Learner
       |         |          |  |  |       |  |
       X-------->|          |  |  |       |  |  Request
       |         X--------->|->|->|       |  |  Prepare(1)
       |         |<---------X--X--X       |  |  Promise(1,{Va,Vb,Vc})
       |         X--------->|->|->|       |  |  Accept!(1,V)
       |         |<---------X--X--X------>|->|  Accepted(1,V)
       |         |          |  |  |       |  !  !! FAIL !!
       |<---------------------------------X     Response
       |         |          |  |  |       |
    

    Proposer 失败时的Basic Paxos流程

    在下面这个图中,Proposer在提出一个值的过程中失败了, 在Acceptor的Accepted返回之前,并且Proposer发送了一个Accept给了法定人数中的某一个Acceptor。

    同时,出现了一个新的Leader(某个Proposer,图中没有画出来),注意图中画了俩轮共识,从上往下

    Client  Proposer        Acceptor     Learner
       |      |             |  |  |       |  |
       X----->|             |  |  |       |  |  Request
       |      X------------>|->|->|       |  |  Prepare(1)
       |      |<------------X--X--X       |  |  Promise(1,{Va, Vb, Vc})
       |      |             |  |  |       |  |
       |      |             |  |  |       |  |  !! Leader fails during broadcast !!
       |      X------------>|  |  |       |  |  Accept!(1,V)
       |      !             |  |  |       |  |
       |         |          |  |  |       |  |  !! NEW LEADER !!
       |         X--------->|->|->|       |  |  Prepare(2)
       |         |<---------X--X--X       |  |  Promise(2,{V, null, null})   -------响应Promise带上先前的Accept的提案,注意后俩个是null。
       |         X--------->|->|->|       |  |  Accept!(2,V)
       |         |<---------X--X--X------>|->|  Accepted(2,V)
       |<---------------------------------X--X  Response
       |         |          |  |  |       |  |

    多个Proposers冲突的Basic Paxos流程

    多个Proposers都相信自己是leader的时候最复杂,比如,当前的leader挂了,待会又恢复了,但是其他的Proposers已经变成了新的leader。从错误中恢复的leader没有学习到最新情况,

    准备开始一轮冲突的操作。如下图所示。有4轮的失败情形,这个情况可能会持续下去(图的最下方)

    Client   Leader         Acceptor     Learner
       |      |             |  |  |       |  |
       X----->|             |  |  |       |  |  Request
       |      X------------>|->|->|       |  |  Prepare(1)
       |      |<------------X--X--X       |  |  Promise(1,{null,null,null})
       |      !             |  |  |       |  |  !! LEADER FAILS
       |         |          |  |  |       |  |  !! NEW LEADER (knows last number was 1)
       |         X--------->|->|->|       |  |  Prepare(2)
       |         |<---------X--X--X       |  |  Promise(2,{null,null,null})
       |      |  |          |  |  |       |  |  !! OLD LEADER recovers
       |      |  |          |  |  |       |  |  !! OLD LEADER tries 2, denied
       |      X------------>|->|->|       |  |  Prepare(2)
       |      |<------------X--X--X       |  |  Nack(2)
       |      |  |          |  |  |       |  |  !! OLD LEADER tries 3
       |      X------------>|->|->|       |  |  Prepare(3)
       |      |<------------X--X--X       |  |  Promise(3,{null,null,null})
       |      |  |          |  |  |       |  |  !! NEW LEADER proposes, denied
       |      |  X--------->|->|->|       |  |  Accept!(2,Va)
       |      |  |<---------X--X--X       |  |  Nack(3)
       |      |  |          |  |  |       |  |  !! NEW LEADER tries 4
       |      |  X--------->|->|->|       |  |  Prepare(4)
       |      |  |<---------X--X--X       |  |  Promise(4,{null,null,null})
       |      |  |          |  |  |       |  |  !! OLD LEADER proposes, denied
       |      X------------>|->|->|       |  |  Accept!(3,Vb)
       |      |<------------X--X--X       |  |  Nack(4)
       |      |  |          |  |  |       |  |  ... and so on ...

    注意:
      上面图中的描述和 Accepted 处的描述有点不同,在 Accepted 中的描述是,Acceptors可以忽略这个Accept请求,但是,在上图中,Acceptors回复了一个Nack,并且带上了最新的提案编号,
      最坏的情况下,这个冲突会持续冲突下去,谁也不能提交成功

      

  • 相关阅读:
    O(1)时间求出栈内元素最小值
    静态查找>顺序、折半、分块查找
    字符串的最大重复数
    数据结构>栈
    排序>归并排序
    动态查找>二叉查找树(Binary Search Tree)
    数据结构>图的存储结构
    数据结构>图的连通性和最小生成树
    图片的轮廓
    数据结构>队列
  • 原文地址:https://www.cnblogs.com/shuiyonglewodezzzzz/p/11643697.html
Copyright © 2011-2022 走看看