天天看點

Paxos - Basic 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沒有收到法定人數響應(Promise和Accepted),在這些情形下,如果發起新的提案。必須使用一個更高的提案編号

沒有任何失敗情形下的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流程

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,并且帶上了最新的提案編号,
  最壞的情況下,這個沖突會持續沖突下去,誰也不能送出成功