paxos算法——此生

Paxos算法

定義2.1  票:即弱化形式的鎖。它具有下面幾個性質:服務器

  • 可從新發布:服務器能夠從新發布新票,即便前面發佈的票沒有釋放。
  • 票能夠過時:客戶端用一張票來給服務器發送命令請求時,只有當這張票是最新的票纔會被服務器接受。

從票的性質中咱們能夠得出以下結論:函數

  • 客戶端崩潰致使死鎖的問題獲得解決,由於服務器能夠發佈新票,從而不影響其餘客戶端。
  • 票能夠避免死鎖的問題,那麼如何實現票,可使用計數器來實現,客戶端向服務器獲取票的請求時,咱們給計算器加1. 當客戶端下次再拿服務器端分配的票時發送命令請求,服務器端能夠根據該票與服務器端的票(計數器)比對來判斷其是否過時,

算法2.1   樸素的基於票的協議。性能

  階段1spa

1: 客戶端向全部的服務器請求一張票變量

  階段2服務器端

2:  if 收到過半數服務器的回覆  then請求

3:        客戶端將得到的票和命令一塊兒發送每一個服務器方法

4:      服務器檢查票的狀態,若是票仍然有效,則存儲命令並給客戶端一個正反饋信息數據

5:else

6:         客戶端等待,並從新進入階段1

7:    end if

    階段3

8:    if 客戶端從過半數服務器處獲得了正反饋  then

9:              客戶端告訴全部的服務器執行以前存儲的命令

10:   else

11:          客戶端等待,而後從新進入階段1

12:   end if 

該算法是有問題的:

  • 假設客戶端  u1 是第一個得到大多數服務器正反饋的客戶端。可是u1很慢,在告知全部服務器執行先前存儲的命令(c1)(算法第9行命令)以前,這時u2更新了部分服務器的票以及存儲了c2命令,這時,執行第9行命令時會致使數據不一致的狀態,部分服務器執行了命令c1,部分服務器執行了命令c2。
  • 如何解決以上的問題呢?若是在階段1中服務器不但發佈票還發布服務器存儲的命令,當u2更新票時,發現服務器端已經存儲了命令c1,這時,客戶端u2能夠不要求服務器存儲命令c2,而是繼續存儲命令c1,這樣兩個客戶端都嘗試執行相同的命令c1,誰先誰後則不在重要。
  • 其次不一樣的服務器可能存放不一樣的命令。在階段1中。客戶端須要支持哪個命令?1.對於得到大多數服務器端都支持的命令,則支持改命令,不然,選擇存儲票據最新的命令。票可使用計數器變量來代替,最新的票,則計數器值最大。
  • 每一個服務端都本身生產票號的話,則最新的票號不必定是最大的。服務器端的票號會存在重複的狀況。若是由客戶端本身來生成票號,這個問題能夠獲得解決。
  • 咱們須要全局一致的票號,所以不能由每一個服務器本身維護一個本地的計數器來產生票號。一個巧妙的辦法是讓客戶端本身來生成票號t,而後向全部的服務器請求編號爲t的票。服務器在收到請求後,先將t和它本地的計數器進行比較,只有t大於本地的計數器時,服務器纔會發佈票(編號爲t),同時將其本地計數器的值更新爲t。這樣就能夠獲得全局一致的產生票號的方法。這就是下面paxos算法所使用的方案。

算法 2.2  Paxos

客戶端(提案者)                                                                                    服務器(接收者)

 初始化………………………………………………………………………………………………………………………………………………………………

  c ——等待執行的命令                                                                                T(max) = 0  —— 當前已發佈的最大票號

  t = 0  —— 當前嘗試的票號                                                                         C = NULL   ——  當前存儲的命令

                                                                                                              T(store) = 0  ——  用來存儲命令C的票

 階段1……………………………………………………………………………………………………………………………………………………………………

 1:t = t + 1

 2: 向全部服務器發消息,請求獲得編號爲t的票

                                                                                                                3:  if t > T(max)   then 

                                                                                                                4:         T(max) = t

                                                                                                                5:          回覆ok(T(store),C)

                                                                                                                6: endif

階段2………………………………………………………………………………………………………………

 7: if 過半服務器回覆ok  then

 8:     選擇T(store)值最大的(T(store),C)

 9:     if  T(store) > 0  then

10:             c = C

11:    endif

12:    向這些回覆了 ok的服務器發送消息:propose(t,c)

13:    endif

                                                                                                                 14:  if  t = T(max).   then

                                                                             15:         C = c

                                                         16:         T(store) = t

                                                         17:          回覆:success

                                                         18:  endif

階段3 ………………………………………………………………………………………………………………

 19:  if  過半服務器回覆  success  then 

 20:     向每一個服務器發送消息:execute(c)

 21: endif 

  • 與前面算法不一樣的是,這個算法沒有明確客戶端從哪一個位置能夠跳轉到階段1並開始新的嘗試。實際上客戶端能夠在算法的任何位置取消當前嘗試並開始新的一輪的嘗試。
  • 在階段1 與階段2 中若是票已通過期,可讓服務器發送負的反饋,這樣能夠提升性能,沒必要等到過半服務器發送正反饋超時而從新嘗試。
  • 連續兩次嘗試之間的等待時間能夠隨機函數肯定,能夠緩和不一樣結點之間的競爭。
相關文章
相關標籤/搜索