一致性哈希

一致性哈希

近期無意接觸到了一致性哈希的內容,所以作爲學習,整合了網上資料加入了個人理解,學習了有關一致性哈希的內容

演變歷史

  1. 最初當我們往集羣裏存入數據時,數據會插入到任意一臺機器上。那查詢時,就需要遍歷每一臺機器才能查詢到我們需要的數據。這樣的效率就會相對低下

  2. 於是爲了改善這種情況,就採取了哈希的方式,針對數據進行哈希計算後,再對機器數取餘數,那麼就可以得到這條數據需要存儲的位置。那通過這樣的方式就能知道這條數據在哪臺機器上,可以快速的命中這條數據,但同樣還是存在着一些缺陷

  3. 當實際環境因爲業務需要增減機器時,那麼哈希取餘數後的值就發生變化了,會導致緩存中的數據失效。當大量緩存同時失效時可能會引起緩存雪崩的現象(在緩存中無法命中數據時,則會把壓力直接傳達到底層數據庫,那大量緩存失效時,數據庫可能會在較大的壓力下的導致集羣崩潰),導致集羣宕機,爲了避免這一現象,引入了一致性哈希

概念

一致性Hash算法也是使用取模的方法,一致性Hash算法是對2^32取模。一致性Hash算法將整個哈希值空間組織成一個虛擬的圓環,如假設某哈希函數H的值空間爲0,1,2,3直至2^32-1(即哈希值是一個32位無符號整形)的一個圓環。這樣的一個圓環被稱作Hash環

節點分佈

假設我們有4臺緩存服務器,服務器A、服務器B、服務器C,服務器D,那麼,在生產環境中,這4臺服務器肯定有自己的唯一標識,我們使用它們各自的唯一標識作爲關鍵字進行哈希計算,使用哈希後的結果對2^32取模,將服務器的哈希值映射到這個圓環上。

數據分配

接下來使用如下算法定位數據訪問到相應服務器: 將數據key使用相同的函數Hash計算出哈希值,並確定此數據在環上的位置,從此位置沿環順時針“行走”,第一臺遇到的服務器就是其應該定位到的服務器。

爲什麼hash一致性的數據空間範圍是2^32次方?
​
因爲,java中int的最大值是2^31-1最小值是-2^31,2^32剛好是無符號整形的最大值;

可擴展性以及容錯性

現假設Node C不幸宕機,可以預想到此時對象A、B、D不會受到影響,本來要入C的對象則順延進入D而已。一般的,在一致性Hash算法中,如果一臺服務器不可用,則受影響的數據僅僅是此服務器到其環空間中前一臺服務器(即沿着逆時針方向行走遇到的第一臺服務器)之間數據,其它不會受到影響。此時對象Object A、B、D不受影響。一般的,在一致性Hash算法中,如果增加一臺服務器,則受影響的數據僅僅是新服務器到其環空間中前一臺服務器(即沿着逆時針方向行走遇到的第一臺服務器)之間數據,其它數據也不會受到影響。綜上所述,一致性Hash算法對於節點的增減都只需重定位環空間中的一小部分數據,具有較好的容錯性和可擴展性。

一致性Hash算法在服務節點太少時,容易因爲節點分部不均勻而造成數據傾斜(被緩存的對象大部分集中緩存在某一臺服務器上)問題,此時會造成大量數據集中到Node A上,而只有極少量會定位到Node B上,從而出現hash環偏斜的情況,當hash環偏斜以後,緩存往往會極度不均衡的分佈在各服務器上,如果想要均衡的將緩存分佈到2臺服務器上,最好能讓這2臺服務器儘量多的、均勻的出現在hash環上,此時就引入了虛擬節點的概念。將現有的物理節點通過虛擬的方法複製出來,即對每一個服務節點計算多個哈希,每個計算結果位置都放置一個此服務節點,稱爲虛擬節點。

 

 


作者:蛋撻

日期:2019.11.20

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