一致性哈希算法


 

一致性哈希算法

 

 

使用場景

現在我們假設有100台redis data服務器,一份數據101進來的時候,以散列公式hash(i)&100,計算所存放的服務器,假設hash(i) = i,那么數據被散列到標號為1的服務器,然后這個時候服務器新增了一台,然后散列公式為hash(i)%101,這個時候請求訪問數據101的時候,被分配至0號服務器,但是其實這個時候數據是在1號服務器的。

所以這個時候大量的數據失效了(訪問不到了)。

所以這個時候,我們假設是新增了服務器,如果是持久化存儲的,我們可以讓服務器集群對數據進行重新散列,進行數據遷移,然后進行恢復,但是這個時候就意味着每次增減服務器的時候,集群就需要大量的通信,進行數據遷移,這個開銷是非常大的。如果只是緩存,那么緩存就都失效了。所以這個時候怎么辦?

我們可以看到,關鍵問題在於,服務器數量變動的時候,要能夠保證舊的數據能夠按照老的算法,計算到數據所在的服務器,而新的數據能夠按照新的散列算法,計算出數據所在的服務器。

如上圖,我們有ABCD四台服務器,這四台服務器被分配至0~232 的一個環上,比如0~230的存儲在A服務器,230 +1~231 存儲到B服務器上.....CD按照這樣的進行均分。將我們的散列空間也划為0~232 ,然后數據進來后對232 取模,得到一個值K1,我們根據K1在環上所處的位置,得到所分配到的服務器,如圖,K1被分配到B服務器。 這個時候,我們有一台服務器B失效了。

 

 

我們可以看到,如果是B失效了,那么如果有持久化存儲的,需要做數據恢復,將B的數據遷移至C即可,對於原本散列在A和D的數據,不需要做任何改變。 同理,如果我們是新增了服務器,那么只需要對一台服務器的數據遷移一部分至新加的服務器即可。

一致性hash算法,減少了數據映射關系的變動,不會像hash(i)%N那樣帶來全局的變動

而且這樣還有個好處,假設我們使用UID作為散列范圍(即上面的232 ),那么假設有部分UID的訪問很頻繁,而且這部分UID集中在B服務器上,那么就造成了B的負載遠遠高於其他服務器。這就是熱點數據的問題。這個時候我們可以向B所在的UID空間添加服務器,減少B的壓力。

其實還有個更好的解決辦法:虛擬節點。

上面說的情況是,使用真實的服務器作為節點散列在232 上。 我們假設,只有4台服務器(如上圖),然后A上面有熱點數據,結果A掛掉了,然后做數據恢復,A的數據遷移至B,然后B需要承受A+B的數據,也承受不住,也掛了。。。。然后繼續CD都掛了。這就造成了

雪崩效應。

上面會造成雪崩效應的原因分析:
如果不存在熱點數據的時候,每台機器的承受的壓力是M/2(假設每台機器的最高負載能力為M),原本是不會有問題的,但是,這個時候A服務器由於有熱點數據掛了,然后A的數據遷移至B,導致B所需要承受的壓力變為M(還不考慮熱點數據訪問的壓力),所以這個失敗B是必掛的,然后C至少需要承受1.5M的壓力。。。。然后大家一起掛。。。
所以我們通過上面可以看到,之所以會大家一起掛,原因在於如果一台機器掛了,那么它的壓力全部被分配到一台機器上,導致雪崩。

如果我們A掛了以后,數據被平均分配到BCD上,每台機器多承受M/6的壓力,然后大家就都不會掛啦(不考慮熱點數據)。

這里引入虛擬節點,如圖:

環上的空間被划分為8份,然后A存儲A1和A2。。。
這個時候,如果A服務器掛了,訪問壓力會分配至C2和D1,也就是C和D服務器,而不是像前面,全部被分配到B上。

引入虛擬節點,主要在於,如果一台服務器掛了,能夠將壓力引流至不同的服務器。

總結:一致性hash算法(DHT)通過減少影響范圍的方式解決了增減服務器導致的數據散列問題,從而解決了分布式環境下負載均衡問題,如果存在熱點數據,那么通過增添節點的方式,對熱點區間進行划分,將壓力分配至其他服務器。重新達到負載均衡的狀態。

tair的負載均衡就是采用的一致性hash算法啦~~~
一致性hash算法在分布式環境中應用的很廣,只要是涉及到分布式存儲的負載均衡問題,一致性hash都是很好的解決的方案。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM