一致性hash的理解

hash

hash即求散列值,可以將不確定長度的數據映射成一串固定值,節省空間且便於比較,通常用在輔助查找,去重等場景。
hash的目的可以用較少的數據空間來體現原有數據的差異性,即同一條數據hash後的值結果肯定是相等的,不等數據的hash後值會盡量分開,這樣的特性便於尋址定位,比如一個數組,我們可以根據hash值對數組長度取模,根據取模位置直接設置和獲取數據。當然由於不同數據的hash值可能相等,我們必須考慮如何解決hash衝突。hashmap,hashset即hash的一個典型應用。

一致性hash

對於分佈式業務,如分佈式緩存業務,在機器不變的情況下,存儲和獲取經過相同的hash算法並對機器數取模是會落在同一臺機器的,但機器數量發生變化後,這樣很可能導致緩存全部失效。一致性hash即爲解決這個問題,在機器增減後,緩存失效的影響最小化。

一致性hash原理及實現

一致性hash採用一個hash環,並順時針找對應機器節點的策略。
在Java中,hashCode爲一個整數,我們將0和最大整數首尾相連,這樣就形成了一個hash環,對緩存機器的ip地址進行hash可以得到一個整數。這個整數對應環上的一個節點,當緩存key過來,我們經過相同的hash算法就可以得到一個整數,它也對應環上的一個點。我們根據這個點在環上順時針找位於它下方的機器節點,找到的第一個即它對應的緩存機器。
這樣,在機器增加或減少中,由於採用順序找的方式,緩存失效影響的範圍將大大縮小,僅限當前節點前後對應的一片區域。
這種思路看起來很美好,但也有缺點,在機器少的情況下,如果兩個機器節點的hash值較接近,在環上的位置也就會較接近,這樣採用順時針找的方式就會造成負載不均衡了,某一個節點可能就承擔了大部分的數據讀寫任務。當然如果是之前的取模是沒這個問題,餘數一般是大致均勻分佈。
解決負載不均衡的辦法即增加虛擬節點,如可以對機器ip統一加標識,使參與hash排點的機器數量變多。如果有幾百個,這樣負載不均衡的概率將大大降低。

總結

一致性hash在分佈式系統中有着廣泛的應用,本質是解決分佈式環境中節點增減後,對整體系統影響最小化的問題。解決思路爲hash環順時針查找,這樣確保影響範圍侷限在一個區域,同時爲解決機器數量少導致的負載均衡問題,又引入了虛擬節點,整體上是一個比較完善的分佈式負載均衡解決方案。

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