強一致性hash實現java版本及強一致性hash原理

一致性 hash

分佈式過程中我們將服務分散到若干的節點上,以此通過集體的力量提升服務的目的。然而,對於一個客戶端來說,該由哪個節點服務呢?或者說對某個節點來說他分配到哪些任務呢?

強哈希

考慮到單服務器不能承載,因此使用了分佈式架構,最初的算法爲 hash() mod n, hash()通常取用戶ID,n爲節點數。此方法容易實現且能夠滿足運營要求。缺點是當單點發生故障時,系統無法自動恢復。同樣不也不能進行動態增加節點。

弱哈希

爲了解決單點故障,使用 hash() mod (n/m),

這樣任意一個用戶都有 m 個服務器備選,可由 client 隨機選取。

由於不同服務器之間的用戶需要彼此交互,所以所有的服務器需要確切的知道用戶所在的位置。

因此用戶位置被保存到 memcached 中。當一臺發生故障,client 可以自動切換到對應 backup,由於切換前另外 1 臺沒有用戶的 session,因此需要 client 自行重新登錄。

  • 好處

他比強哈希的好處是:解決了單點問題。

  • 缺點

但存在以下問題:負載不均衡,尤其是單臺發生故障後剩下一臺會壓力過大;不能動態增刪節點;節點發生故障時需要 client 重新登錄

一致性 hash 算法

一致性 hash 算法提出了在動態變化的 Cache 環境中,判定哈希算法好壞的四個定義:

平衡性(Balance)

平衡性是指哈希的結果能夠儘可能分佈到所有的緩衝中去,這樣可以使得所有的緩衝空間都得到利用。很多哈希算法都能夠滿足這一條件。

單調性(Monotonicity)

單調性是指如果已經有一些內容通過哈希分派到了相應的緩衝中,又有新的緩衝加入到系統中。哈希的結果應能夠保證原有已分配的內容可以被映射到原有的或者新的緩衝中去,而不會被映射到舊的緩衝集合中的其他緩衝區。

分散性(Spread)

在分佈式環境中,終端有可能看不到所有的緩衝,而是隻能看到其中的一部分。

當終端希望通過哈希過程將內容映射到緩衝上時,由於不同終端所見的緩衝範圍有可能不同,從而導致哈希的結果不一致,最終的結果是相同的內容被不同的終端映射到不同的緩衝區中。

這種情況顯然是應該避免的,因爲它導致相同內容被存儲到不同緩衝中去,降低了系統存儲的效率。分散性的定義就是上述情況發生的嚴重程度。好的哈希算法應能夠儘量避免不一致的情況發生,也就是儘量降低分散性。

負載(Load)

負載問題實際上是從另一個角度看待分散性問題。既然不同的終端可能將相同的內容映射到不同的緩衝區中,那麼對於一個特定的緩衝區而言,也可能被不同的用戶映射爲不同的內容。

與分散性一樣,這種情況也是應當避免的,因此好的哈希算法應能夠儘量降低緩衝的負荷。

普通的哈希算法(也稱硬哈希)採用簡單取模的方式,將機器進行散列,這在cache環境不變的情況下能取得讓人滿意的結果,但是當cache環境動態變化時,
這種靜態取模的方式顯然就不滿足單調性的要求(當增加或減少一臺機子時,幾乎所有的存儲內容都要被重新散列到別的緩衝區中)。

代碼實現

實現邏輯

一致性哈希算法有多種具體的實現,包括 Chord 算法KAD 算法等實現,以上的算法的實現都比較複雜。

這裏介紹一種網上廣爲流傳的一致性哈希算法的基本實現原理,感興趣的同學可以根據上面的鏈接或者去網上查詢更詳細的資料。

一致性哈希算法的基本實現原理是將機器節點和key值都按照一樣的hash算法映射到一個0~2^32的圓環上。

當有一個寫入緩存的請求到來時,計算 Key 值 k 對應的哈希值 Hash(k),如果該值正好對應之前某個機器節點的 Hash 值,則直接寫入該機器節點,
如果沒有對應的機器節點,則順時針查找下一個節點,進行寫入,如果超過 2^32 還沒找到對應節點,則從0開始查找(因爲是環狀結構)。

如圖 1 所示:

hash

圖 1 中 Key K 的哈希值在 A 與 B 之間,於是 K 就由節點B來處理。

另外具體機器映射時,還可以根據處理能力不同,將一個實體節點映射到多個虛擬節點。

經過一致性哈希算法散列之後,當有新的機器加入時,將隻影響一臺機器的存儲情況,

例如新加入的節點H的散列在 B 與 C 之間,則原先由 C 處理的一些數據可能將移至 H 處理,
而其他所有節點的處理情況都將保持不變,因此表現出很好的單調性。

而如果刪除一臺機器,例如刪除 C 節點,此時原來由 C 處理的數據將移至 D 節點,而其它節點的處理情況仍然不變。

而由於在機器節點散列和緩衝內容散列時都採用了同一種散列算法,因此也很好得降低了分散性和負載。

而通過引入虛擬節點的方式,也大大提高了平衡性。

實現代碼

consitent-hashing

原文地址

consitent-hashing

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