《Object Storage on CRAQ: High-throughput chain replication for read-mostly workloads》論文總結

CRAQ 論文總結

說明:本文為論文 《Object Storage on CRAQ: High-throughput chain replication for read-mostly workloads》 的個人理解,難免有理解不到位之處,歡迎交流與指正 。

論文地址CRAQ Paper


0. 簡介

Chain Replication with Apportioned Queries (CRAQ) 是一種對鏈式複製的改進,它通過在所有對象副本上分配負載,在保持強一致性的同時極大地提高了讀吞吐量。

本文主要對鏈式複製、CRAQ 原理以及 CRAQ 的一致性模型做出總結。


1. 對象存儲

基於對象 的存儲中,數據作為整個單元呈現給應用程序。

對象存儲支持兩種基本原語:

  • readquery 操作返回存儲在對象名稱下的數據塊
  • writeupdate 操作更改單個對象的狀態

對象存儲更適合於平面名稱空間,例如鍵值數據庫,而不是層次目錄結構。對象存儲簡化了支持整個對象修改的過程,通常,它們只需要考慮對特定對象的修改順序,而不是整個存儲系統。為每個對象提供一致性保證成本要低得多。


2. 一致性模型

本文涉及到的兩種一致性模型為:

  • 強一致性:系統保證對一個對象的讀寫操作都以順序執行,並且對於一個對象的讀操作總是會觀察到最新被寫入的值。
  • 最終一致性:在系統中,對一個對象的寫入仍是按順序在所有節點上應用的,但對不同節點的最終一致性讀取可能會在一段時間內(即,在寫操作應用於所有節點之前)返回過時的數據。但是,一旦所有副本都接收到寫入操作,則讀操作將不會返回比最新提交的寫操作更早的版本。事實上,如果一個 client 維護與特定節點的會話,那麼它也會看到單調的讀一致性。

3. 鏈式複製

鏈式複製 (Chain Replication、CR) 是一種跨多個節點複製數據的方法:

  • 節點形成一個長度為 C 的鏈
  • 鏈的頭部節點處理來自客戶端的所有寫操作
  • 當一個節點接收到寫操作時,它將傳播到鏈中的每一個節點
  • 一旦寫入到達尾部節點,它就被應用於鏈中的所有副本,並且被認為是提交的
  • 當尾節點提交寫操作時,會向客戶端發送一個回復
  • 尾部節點處理所有讀操作,因此只有提交的值才能由讀操作返回

鏈式複製實現了 強一致性:由於所有的讀操作都是在尾部進行的,而所有寫操作都在尾部提交,所以鏈尾可以簡單地對所有操作應用一個總的順序。

鏈式複製的簡單拓撲使得寫操作比提供強一致性的其他協議消耗更小。如在 Raft 中,leader 需要將每次寫操作都發送給所有的 follower ,但是 CRAQ 中,head 只需要將每一次寫操作發送一次;並且 Raftleader 需要處理讀寫操作,而 CRAQ 中的 head 只需要處理寫操作。

鏈式複製的 故障恢復

  • 當頭節點出故障時:後續節點取代它成為頭節點,沒有丟失的已提交寫操作
  • 當尾節點出故障時:前一個節點取代它成為尾節點,沒有丟失的寫操作
  • 當中間節點故障時:從鏈中去掉,前一個節點需要重新發送最近的寫操作

局限性:對一個對象的所有讀取必須都要轉到同一個節點,尾節點的負載很大。


4. CRAQ

4.1 CRAQ原理

CRAQ 是鏈式複製的一種改進,它允許鏈中的任何節點執行讀操作:

  • CRAQ 每個節點可以存儲一個對象的多個版本,每個版本都包含一個單調遞增的版本號和一個附加屬性( 標識 clean 還是 dirty

  • 當節點接收到對象的新版本時(通過沿向下傳播的寫操作),該節點將此最新版本附加到該對象的列表中

    • 如果節點不是尾節點,則將版本標記為 dirty ,並向後續節點傳遞寫操作
    • 如果節點是尾節點,則將版本標記為 clean ,此時寫操作是 已提交 的。然後,尾節點在鏈中往回發送 ACK 來通知其他節點提交
  • 當對象版本的 ACK 到達節點時,該節點會將對象版本標記為 clean 。然後,該節點可以刪除該對象的所有先前版本

  • 當節點收到對象的讀請求時:

    • 如果請求的對象的最新已知版本是乾淨的,則節點將返回此值
    • 否則,節點將與尾節點聯繫,詢問尾節點上該對象的最後提交版本號,然後,節點返回該對象的此版本

4.2 CRAQ性能提升

CRAQ 相對於 CR 的吞吐量改進發生在兩種不同情況下:

  • 讀密集型工作負載:讀操作可以在所有節點上執行,因此吞吐量與鏈長度呈線性比例關係
  • 寫密集型工作負載:大量寫操作的工作負載中,更容易讀取到 dirty 數據,因此對尾節點的查詢請求比較多。但是對尾節點查詢的工作負載遠低於所有讀請求都由尾節點來執行的工作負載,因此 CRAQ 吞吐量高於 CR

4.3 CRAQ的一致性模型

對於讀操作, CRAQ 支持三種一致性模型:

  • 強一致性4.1 中描述的讀操作可以使每次讀取都讀到最新寫入的數據,因此提供了強一致性
  • 最終一致性:允許節點返回未提交的新數據,即允許 client 可從不同的節點讀到不一致的對象版本。但是對於一個 client 來說,由於它與節點建立會話,所以它的讀操作是保證單調一致性的。
  • 帶有最大不一致邊界的最終一致性:允許節點返回未提交的新數據,但是有不一致性的限制,這個限制可以基於版本,也可以基於時間。如允許返回一段時間內新寫入但未提交的數據。

4.4 split-brain 問題

若兩個相鄰節點之間的網絡連接斷開,後面的節點會想去成為頭節點,這樣就會產生兩個頭節點。

CRAQ 本身並不會解決這樣的問題,所以需要外部的分佈式協調服務來解決這一問題,如使用 Zookeeper 。由 Zookeeper 來決定鏈的組成,決定哪個節點是頭、尾,並監控哪個節點出了故障。當發生網絡故障時,由 Zookeeper 來決定鏈的新組成,而不是基於各節點對於網絡情況的自身感知。