- 強一致性:在任意時刻,從任意不同副本取出的值都是一樣的。
- 弱一致性:有時泛指最終一致性,是指在任意時刻,可能由於網絡延遲或者設備異常等原因,不同副本中的值可能會不一樣,但經過一段時間后,最終會變成一樣。
顯然,我們更想要做到強一致性的這種效果,那么有哪些方式可以實現呢,其中最為簡單直接的就是WARO,也就是Write All Read one。
WARO協議
是一種簡單的副本控制協議,當 Client 請求向某副本寫數據時(更新數據),只有當所有的副本都更新成功之后,這次寫操作才算成功,否則視為失敗。這樣的話,只需要讀任何一個副本上的數據即可。但是WARO帶來的影響是寫服務的可用性較低,因為只要有一個副本更新失敗,此次寫操作就視為失敗了。
到這里,再來看Quorum機制到底是個什么鬼?他比WARO又好在什么地方
Quorum機制
Quorum 的定義如下:假設有 N 個副本,更新操作 wi 在 W 個副本中更新成功之后,則認為此次更新操作 wi 成功,把這次成功提交的更新操作對應的數據叫做:“成功提交的數據”。對於讀操作而言,至少需要讀 R 個副本,其中,W+R>N ,即 W 和 R 有重疊,一般,W+R=N+1。
-
N = 存儲數據副本的數量
-
W = 更新成功所需的副本
-
R = 一次數據對象讀取要訪問的副本的數量
聽起來有些抽象,舉個例子:
假設我有5個副本,更新操作成功寫入了3個,另外2個副本仍是舊數據,此時在讀取的時候,只要確保讀取副本的數量大於2,那么肯定就會讀到最新的數據。至於如何確定哪份數據是最新的,我們可以通過引入數據版本號的方式判斷(Quorum 機制的使用需要配合一個獲取最新成功提交的版本號的 metadata 服務,這樣可以確定最新已經成功提交的版本號,然后從已經讀到的數據中就可以確認最新寫入的數據。)
Quorum的應用
Quorum在分布式系統中的應用很多,下面舉幾個比較典型的例子:
1、HDFS HA
為解決NameNode的單點問題,在Hadoop 2.0對HDFS的高可用進行了改進,使得系統中可以同時啟動多個NameNode,一個Active,一個Standby,並使用ZKFC(ZKFailoverController)對兩者進行監控,當發現Active的NameNode服務中斷,Standby的NameNode的狀態會自動變為Active,接替原ActiveNameNode對外提供服務。
要想實現上面的功能,那就必然需要一個機制來確保Active和Standby這兩個NameNode中的數據一致,所以在該系統中還引入了一個QJM模塊,全稱為Quorum Journal Manager。該模塊一般由奇數個結點構成,每個QJM結點對外有一個RPC接口,以供Active NameNode向QJM寫入EditLog(操作日志),此時會要求半數以上的QJM都寫入成功,才算此次操作成功。Standby的NameNode也會定期從QJM上獲取最新的EditLog來更新自身的數據。

2、Zookeeper
Zookeeper的選舉機制是遵循了Quorum的,這也是為什么我們部署Zookeeper必須要求有奇數個Cluster可用的原因。這樣一是能保證Leader選舉時不會出現平票的情況,避免出現腦裂。二是Leader在向Follower同步數據的時候,必須要超過半數的Follower同步成功,才會認為數據寫入成功。
其實除了Zookeeper以外,很多支持分布式部署的模塊,也都遵循和使用了這個設計,比如Redis的哨兵(sentinel)機制。
