Keyspace中的paxos [轉載]

1. Keyspace

Keyspace是一款基於Paxos的開源Key-Value的數據庫,底層存儲基於BerkelyDB,Keyspace的核心功能是在 BerkelyDB之上添加了一致層,保證每個節點的數據完全一致。Keyspace基於Master-Slave模式,所有的寫均有Master承擔, 並通過paxos一致傳播到slave,讀可以根據基本路由到master或slave。因此,當master出現宕機或不可訪問時,會存在一套 master的選舉機制,在keysapce中成爲PaxosLease算法。默認,master擁有Lease的時間是7秒,但只要master沒有 crash可以繼續持有。

要指出的是,因爲基於master,所有keyspace對paxos實現進行了改造,把2 phase的paxos改造爲1 phase。

2. Keyspace配置

Keyspace提供了衆多的端口和服務,具體如下:

Item Port
HTTP服務 8080
非HTTP客戶端 7080
內部 數據複製 10000
master lease 10001
catch up 10002

Catch UP是指節點長時間離開後又加入的情況

3. Keyspace架構

Keysapce的基本架構是在BerkelyDB之上加了一層paxos,其圖如下:


Paxos與PaxosLease同屬於Paxos層,PaxosLease傾向於解決Leader選舉問題,Paxos主要是解決數據一致性,我們重點放在Paxos上。

在Paxos的實現上,Keysapce還有幾個描述更細緻的組件:

  • KeyspaceDB:對外部協議的一致性操作接口,隱藏了對Paxos和BerkelyDB的調用。
  • ReplicatedLog:邏輯上的DB Log,封裝了Paxos的一致性
  • PaxosProposer:Paxos算法中的提案者
  • PaxosAcceptor:Paxos算法中的acceptor
  • PaxosLearn:Paxos算法中的Learn

在Keysapce中的每個節點都集Proposer、Acceptor、Learn三種角色於一身,有ReplicatedLog統一協調。

另,Keyspace使用的是TCP協議,其他非核心模塊、功能則不再介紹。

4.Paxos實現

Keyspace採用了基於Master的Paxos算法,只要Master沒有crash,所有的寫請求均有Master上的proposer進 行提案,並一致性地寫到所有的slave。因爲Master的存在,Keyspace把傳統paxos算法的prepare、accept兩個階段,簡化 爲僅有prepare的1個階段,但keyspace對prepare階段的兩個過程進行了概念上的重新定義:

  • propose:master提出proposal
  • prepare resposne:acceptor對proposer的response

如果因爲網路延遲或其它原因導致master提交的proposal被拒,則master需要提高proposal的編號繼續提交,此時稱爲:

  • prepare:master提供編號後繼續提交proposal
  • prepare response:對應的response

以前paxos算法中的proposal是個抽象的概念,但在Keyspace中是非常具體的,就是Key-value對。那paxos是如何保證一致性的呢?每次用戶提交Key-value,Keyspace都進行下面流程:

  1. ReplicatedLog把接收到的Key-Value傳遞給Master Proposer
  2. Master給當前的(K,V)分配paxosID即instance id,並作爲propose消息發送給其他的Node
  3. 之前其他Node的多數派都響應了accept消息,Master便把該(K,V)連通paxosID一起發送給所有的Learn(也是其他Node)
  4. Learn 在接收到Master的消息後,會檢查消息中的paxosID之前所有的paxosID是否已經學習過了,即保證(K,V)要按順序執行,不能跳號。如果 之前的均已學習過了,則把當前paxosID對應的(K,V)持久化到BerkelyDB;否則Learn要請求Master學習之前的paxosID對 應的消息。

按編號順序學習消息是Keyspace保證一致性複製的核心。我們在詳細說明下4的過程,在Learn收到消息(msg)後要檢查:

  • 如果msg.paxosID==local.paxosID+1,這直接執行消息中的(K,V)
  • 如果local.paxosID < msg.paxosID,則需首先學習[local.paxosId+1,msg.paxosId-1]對應的(K,V),然後在執行msg.paxosID對應的(K,V)已保證一致性,這個過程稱爲跳號

爲了節省空間,master會緩存一部分已經發送的paxosID,也即最新數據,比如爲[minPaxosId,maxPaxosId]:

  • 在Master收到跳號請求時,要查詢Master本地緩存中已經發送過的paxosID:
    • 如果minPaxosId<=msg.paxosId<=maxPaxosId,則直接從緩存中取出
    • 否則Master迴應Learn,指示其應該進行catch up,catch up的意思是需要從master上傳輸大量數據,有可能是全部數據,以保證learn與master一致。
  • 在Learn收到catch up消息後,立即啓動catch up過程,把Master上的數據全複製過來,從而保證了一致性

持久化

Keyspace無論是對paxosID的緩存還是最終數據,都是持久化到了BerkelyDB,這就保證了Node重啓後算法的正確性。

容錯

Keysapce做了很好的持久化,並充分相信BerkelyDB,可以解決網絡、宕機等衆多失敗,但對BerkelyDB失敗的情況是無法處理的,在實際中可以參考其catch up實現

問題

Keyspace的特點是所有的寫都經過Master,所有的Node數據都與Master保持一致,但在實際中,需要的是動態分片、複製,而不是所有的節點數據都完全一致,因此跟Keyspace宣稱的一樣,它的目標只是做一個分佈式底層,而不是終端產品。

5. Master選舉

很顯然,還有一個要解決的問題是Master宕機後如何選擇新的Master,請參考:http://blog.csdn.net/chen77716/archive/2011/03/21/6265394.aspx

6. 疑問

在Keyspace對Paxos算法進行大刀闊斧地改造後,我們不僅要問這還是paxos算法嗎?不考慮Master選舉,這明明就是一個有Master來保證的一致性問題。

的確是的,但因爲有網絡延遲、節點重啓、磁盤失敗等諸多情況,如果沒有多數派的投票機制,僅靠Master還是很難保證一致性,尤其是錯誤情況下的 正確性,因此,改造後的還是paxos算法,Google Chubby的人曾說,任何分佈式一致性算法都是paxos的特例,這也算是特例之一。

其實原生的Paxos算法很難不加任何改造就在工程中實現,因爲其有性能問題,這一點微軟的人也說過。所以,不必在乎是否是血統純正的paxos算法,只要把握住要領靈活應用即可,paxos不是有形的劍,而是無形的氣,看你如何駕馭它,而不是被它駕馭。

發佈了151 篇原創文章 · 獲贊 3 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章