衝突的處理,也是分佈式系統中一個重要的議題。今天咱們繼續以 Riak 爲案例,看看 Riak 是怎麼作衝突處理的。數據庫
Riak 經過一種叫作 Vector Clock
的機制來處理衝突問題。簡單來講,Vector Clock
是一段 token
,
像 Riak
這樣的分佈式系統經過這樣的 token
來追蹤數據更新操做的前後順序。服務器
在衝突處理中,可以知道衝突操做(eg. 建立操做,更改操做)的順序,是很是重要的。
由於對於分佈式系統來講,不一樣的客戶端鏈接到的是不一樣的服務器節點,
當一個客戶端更新了一個服務器節點上的數據,也許另外一個客戶端也同時更新了另外一個服務器節點上的數據。分佈式
這時候,也許你會想到:記錄每一個操做的時間戳,而後依照時間戳靠後的操做來。然而要這麼作的話,這裏有個隱含的前提:
在這個分佈式系統中的每一個服務器節點,時鐘都必須是徹底同步的。
然而事實上,一方面這是很是困難的:須要很是大的財力物力的投入;另外一方面,整個系統又是單點故障的。版本控制
因此,Riak 使用 Vector Clocks
來處理衝突。Vector Clocks
給每一個寫操做(建立,更改,刪除) 打上一個標籤,標籤表明了是哪一個客戶端以什麼樣的順序執行的操做。
這樣一來,客戶端或者開發者就能決定面對衝突,該怎麼決定。
若是你熟悉像 Git
, Subversion
這樣的版本控制系統,
這就和兩我的同時修改了同一個文件產生的衝突解決思路是類似的。code
Vector Clock
小故事 —— Vector Clock
相關理論暴走大事件的編輯部每週都要整理下一期裏要播報的新聞段子。token
假設負責整理新聞段子有3我的:王尼瑪(A), 張全蛋(B), 紙巾(C)。他們須要肯定最終的新聞段子的列表。新聞段子的列表存儲在分佈式的服務器中。事件
每一個人用本身的終端鏈接數據庫。這些終端都有着惟一的標識,用來構建 vector clock。下面就讓咱們模擬一下,vector clock 是如何工做的。開發
首先,王尼瑪用本身的終端更新了列表同步
vclock: A[0] value: ['news xx']
而後,張全蛋先下載了這個列表,而後更新了這個列表it
vclock: A[0], B[0] value: ['news xx', 'news xyy']
張全蛋更新的同時(王尼瑪作更新以後),紙巾一樣的下載了已有的列表,作了更新。
vclock: A[0], C[0] value: ['news xx', 'news yyz']
次日,張全蛋複查列表,因爲紙巾的更新操做並非在他以後的(而是和他同時的),
這時候就產生了一個衝突,須要處理。
他拿到兩個值:
vclock: A[0], B[0] value: ['news xx', 'news xyy'] -- vclock: A[0], C[0] value: ['news xx', 'news yyz']
他須要解決這個衝突:因而他選擇合併這兩個值:
vclock: A[0], C[0], B[1] value: ['news xx', 'news xyy', 'news yyz']
這樣一來,任何人以後獲取到的就是這個最新的合併後的值了。