【原創】分佈式一致性算法之(NRW&Vector Clock)

         分佈式系統爲了保證一致性,有一個非常著名的算法PAXOS,這個也是目前經過證明的保證能夠保證強一致性(strong consistency)的唯一算法。PAXOS算法也是唯一保證了在非拜占庭(參考拜占庭將軍問題)情況下, 2F+1個副本節點中,有F個副本節點存在故障,仍然能夠保證數據讀寫強一致性。

PAXOS算法需要多輪副本節點間的交互才能達成一致讀寫,負載和延時比較大。多數分佈式系統中的設計理念是在CAP中優先選擇AP,對於C採用的是eventual consistency,大規模部署時能夠提升上層業務的可用性。

(一)NRW       

         Amazon Dynamo一樣的NRW機制,NRW的本質一個Quorum機制。N代表數據的副本數目,R代表了一次成功讀操作需要讀到的最少副本數目,W代表了一次成功寫操作需要讀到的最少副本數目。當R+W>N時,按照Quorum機制的證明,僅僅只能保證寫W個副本成功後,讀R個副本中一定有最新寫入的數據。

NRW在Dynamo內部可以爲不同的store配置不同的參數。典型的配置如322,以爲系統爲每個數據設置3個副本,寫請求要至少寫成功2個節點纔算請求成功,讀請求要至少寫成功2個節點纔算請求成功,這樣讀寫請求都可以允許一個節點發生故障,提升可用性,選擇這些值是爲滿足性能,耐用性,一致性和可用性SLAs的需求。有些系統也可以配置爲313,這就要求寫請求必須3個全部寫成功纔算成功,在寫操作的過程中,不允許任何節點故障。

        一定會保障讀到新數據,但是讀到的R個副本中哪個是最新的並不是NRW機制能夠解決的問題,需要採用Vector Clock或TimeStamps來解決。

(二) Vector Clock

         Vector Clock是一種向量鎖機制,實現爲一個{node, counter}的列表,SoD存儲的每個Key-value都有一個vector clock,用來標記每個數據的版本。其中Node代表的是SoD節點號,counter代表的是該對象被更新的次數,據此可以判斷一個對象的多個副本之間的新老版本關係。Vector clock只有在寫的時候才更新,讀的時候保持不變。寫數據時node號是該key-value對應的主節點的node id。

舉例如有A,B,C三個節點,N=3:

(1). put(key, value)後,A,B,C節點上的數據記錄爲:(key, value, {A,0});

(2). Put (key, value2)後,A, B, C節點上的數據記錄爲:(key, value, {A, 1});

根據Vector Clock可以對比出數據版本的先後關係,比如同一個key,value數據,在節點A,B,C上的數據記錄分別爲:

A: (key, value, {A, 2})

B: (key, value, {A, 2}{B,1})

C: (key, value, {A, 3})

則節點B上版本比A新,節點C上版本比A新,當客戶端讀請求獲取R=2個副本數據時,無論是A和B,或者A和C,都可以根據vector clock比對出哪個是新數據,保證了讀寫一致性。則點B和節點C的版本衝突,無法通過vector clock對比出新老關係,需要上層應用來解決版本衝突問題。導致版本B和C節點上同一個key數據版本衝突,是由集羣內節點故障時序不同導致的,特別是在多個客戶端併發讀寫同一個數據時產生。具體場景請參考場景序列圖[

      在Dynamo這種弱一致性的系統中,即便採用R+W>N的讀寫因子,也會出現版本衝突,需要上層應用在編寫程序時解決這個問題。當前SoD在每個Vector Clock中加入了timestamp,一旦出現上述版本衝突問題,上層可根據時間戳來判斷新舊關係。另外, Vector Clock中{node, counter}列表會隨着處理主節點變化而不斷增長,有些系統內部會對vector clock列表根據時間戳先後關係進行裁剪,防止vector clock列表增長過大。Vector clock列表信息也稱爲version信息。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章