概念解說 · 分散式系統

最終一致性的真正代價

你有一份資料,要放在 N 個複本(replica)上做容錯。某天一台機器壞了、或者你想加裝一台新的。 系統需要搬多少資料才能恢復平衡?傳統做法(用 hash(key) mod N 直接分片)的答案是「幾乎全部」。 把複本擺在一個圓環上、用「順時針找下一個」的規則指派擁有權,可以把搬遷量壓到大約 K / N。 下面是為什麼。

關鍵想法:把節點擺在環上,不要擺在線上

把每個 複本節點 和每筆資料都用同一個雜湊函數, 投影到同一個 (雜湊輸出空間,頭尾相接)。 一筆資料屬於哪個節點?從它的位置順時針走,第一個遇到的節點就是它的主人。 當某個節點離開時,只有它那一段 上的資料需要轉手—— 交給順時針方向的下一個鄰居——其他資料的歸屬完全不動。

4
32
4 個節點 · 32 筆資料 · 上次變動搬遷

不同顏色的弧代表不同節點的擁有權範圍。移除一個節點時,它的弧合併到順時針鄰居; 其他弧上的每一個點(資料)顏色不變——這就是整個機制要保護的不變量。

對照組:hash mod N 為什麼不行

hash mod N環狀指派
N→N+1 時資料搬遷比例約 (N−1)/N 全部要動約 1/(N+1)
負載均勻度建構上即均勻會偏斜——用 虛擬節點 修正
查詢成本O(1)O(log N)(環上做二分搜尋)
實際使用者陣列分片、簡單負載均衡器Dynamo、Cassandra、Memcached client、Envoy

什麼場景會遇到

只要你正在把狀態分散到一個大小會變動的池子裡:快取叢集、分片佇列、物件儲存、有 sticky session 的請求路由。 實際生產環境跑的並不是「一個物理節點對應環上一個點」這種樸素版,而是 虛擬節點 版本—— 每個物理節點佔據環上很多小弧,而不是一條大弧。這樣負載更平均,加減機器時的擾動也更小。

理解這個機制的真正價值,不是記住一個演算法名字,而是看穿一個更普遍的設計權衡: 當系統規模會動態變化,你寧可付出 O(log N) 的查詢成本,也不願意付出 O(N) 的重平衡成本。 這個取捨在很多地方反覆出現——一致性 hash 只是它最乾淨的範例之一。