在分散式資料庫(如 Dynamo、Riak、Cassandra)中,為了高可用與分區容錯,常採用**多主複製**架構:多個節點同時接受寫入,資料最終一致性透過背景同步實現。但並發寫入會導致版本衝突,例如:
price = 5888price = 6888向量時鐘是解決此類問題的經典算法,提供**因果關係追蹤**與**衝突檢測**能力。
假設叢集有 N 個副本節點,每個資料項攜帶一個 N 維向量:
VC = [Node_A: v_A, Node_B: v_B, Node_C: v_C, ...]
[A:0, B:0, C:0]| 步驟 | 操作 | 節點 A | 節點 B | 節點 C | 向量時鐘 |
|---|---|---|---|---|---|
| 1 | 初始 | 5888 | 5888 | 5888 | [A:0,B:0,C:0] |
| 2 | Client 寫入 A | 5888 | 5888 | 5888 | [A:1,B:0,C:0] |
| 3 | A 同步至 B、C | 5888 | 5888 | 5888 | [A:1,B:0,C:0] |
| 4 | Client 寫入 B(價格 6888) | 5888 | 6888 | 5888 | [A:1,B:1,C:0] |
| 5 | B 同步至 A、C | 6888 | 6888 | 6888 | [A:1,B:1,C:0] |
| 6 | Client 寫入 C(價格 4000) | 6888 | 6888 | 4000 | [A:1,B:1,C:1] |
| 7 | C 僅同步至 A(網路分區) | 4000 | 6888 | 4000 | A:[A:1,B:1,C:1] B:[A:1,B:1,C:0] |
| 8 | Client 寫入 B(價格 6000) | 4000 | 6000 | 4000 | B:[A:1,B:2,C:0] |
| 9 | B 同步至 A、C | 衝突發生 | A:[A:1,B:1,C:1] vs B:[A:1,B:2,C:0] | ||
給定兩向量 VC1、VC2,逐維度比較:
VC1 < VC2):∀i, VC1[i] ≤ VC2[i] 且 ∃j, VC1[j] < VC2[j]節點收到遠端版本 VC_remote,本地版本 VC_local:
VC_local < VC_remote):採用遠端值,VC 取各維度最大值VC_local > VC_remote):拒絕遠端版本,保持本地向量時鐘**僅檢測衝突,不解決衝突**。常見解決方案:
timestamp,取時間較新者。向量擴展為 [A:1,B:2,C:0, ts:123456789]。缺點:時鐘不同步可能導致資料丟失向量時鐘以**每節點一個計數器**精確捕捉分散式系統中的因果關係,是最終一致性系統實現版本控制、衝突檢測的基石。理解其比較規則、合併邏輯與衝突解決策略,是設計高可用分散式存儲系統的必修課。