說明:本文爲論文 《Object Storage on CRAQ: High-throughput chain replication for read-mostly workloads》 的我的理解,不免有理解不到位之處,歡迎交流與指正 。git
論文地址:CRAQ Papergithub
Chain Replication with Apportioned Queries (CRAQ) 是一種對鏈式複製的改進,它經過在全部對象副本上分配負載,在保持強一致性的同時極大地提升了讀吞吐量。數據庫
本文主要對鏈式複製、CRAQ 原理以及 CRAQ 的一致性模型作出總結。網絡
在 基於對象 的存儲中,數據做爲整個單元呈現給應用程序。分佈式
對象存儲支持兩種基本原語:性能
read
或 query
操做返回存儲在對象名稱下的數據塊write
或 update
操做更改單個對象的狀態對象存儲更適合於平面名稱空間,例如鍵值數據庫,而不是層次目錄結構。對象存儲簡化了支持整個對象修改的過程,一般,它們只須要考慮對特定對象的修改順序,而不是整個存儲系統。爲每一個對象提供一致性保證成本要低得多。code
本文涉及到的兩種一致性模型爲:對象
鏈式複製 (Chain Replication、CR) 是一種跨多個節點複製數據的方法:blog
鏈式複製實現了 強一致性:因爲全部的讀操做都是在尾部進行的,而全部寫操做都在尾部提交,因此鏈尾能夠簡單地對全部操做應用一個總的順序。get
鏈式複製的簡單拓撲使得寫操做比提供強一致性的其餘協議消耗更小。如在 Raft 中,leader 須要將每次寫操做都發送給全部的 follower ,可是 CRAQ 中,head 只須要將每一次寫操做發送一次;而且 Raft 中 leader 須要處理讀寫操做,而 CRAQ 中的 head 只須要處理寫操做。
鏈式複製的 故障恢復:
侷限性:對一個對象的全部讀取必須都要轉到同一個節點,尾節點的負載很大。
CRAQ 是鏈式複製的一種改進,它容許鏈中的任何節點執行讀操做:
CRAQ 每一個節點能夠存儲一個對象的多個版本,每一個版本都包含一個單調遞增的版本號和一個附加屬性( 標識 clean
仍是 dirty
)
當節點接收到對象的新版本時(經過沿向下傳播的寫操做),該節點將此最新版本附加到該對象的列表中
dirty
,並向後續節點傳遞寫操做clean
,此時寫操做是 已提交
的。而後,尾節點在鏈中往回發送 ACK
來通知其餘節點提交當對象版本的 ACK
到達節點時,該節點會將對象版本標記爲 clean
。而後,該節點能夠刪除該對象的全部先前版本
當節點收到對象的讀請求時:
CRAQ 相對於 CR 的吞吐量改進發生在兩種不一樣狀況下:
dirty
數據,所以對尾節點的查詢請求比較多。可是對尾節點查詢的工做負載遠低於全部讀請求都由尾節點來執行的工做負載,所以 CRAQ 吞吐量高於 CR。對於讀操做, CRAQ 支持三種一致性模型:
若兩個相鄰節點之間的網絡鏈接斷開,後面的節點會想去成爲頭節點,這樣就會產生兩個頭節點。
CRAQ 自己並不會解決這樣的問題,因此須要外部的分佈式協調服務來解決這一問題,如使用 Zookeeper 。由 Zookeeper 來決定鏈的組成,決定哪一個節點是頭、尾,並監控哪一個節點出了故障。當發生網絡故障時,由 Zookeeper 來決定鏈的新組成,而不是基於各節點對於網絡狀況的自身感知。