一文讓你徹底明白什麼是一致性哈希

前言

要了解一致性哈希,我們先從經典的服務器結構說起。

----------------------------------------------------------------------------------------------------------------------

 

經典服務器結構

整個服務器的結構由前端負載服務器(圖中的4個小圈圈代表4臺前端負載服務器,用於分流)後端的服務器(圖中的三個小方塊,m0、m1、m2代表三臺後端服務器,用於存放數據)組成。

此時客戶端發來兩條數據{「xu」,666}和{"jian",888},經過前端負載服務器把"xu"和"jian"分別進行hash("xu")和hash("jian")的操作然後模3(因爲只有3臺機器)分別得到hash("xu")%3=0,hash("jian")%3=2,然後分別把{"xu",666}和{"jian",888}兩條數據分別存放在m0和m2上。

這種是經典的服務器結構,它在前端服務器上使用hash函數把數據分流到m0、m1、m2上,因爲hash函數具有大樣本的情況下均勻分佈的特徵,因此m0、m1、m2可以進行抗壓,而不是一堆數據都存在一個服務器上,這叫做負載均衡

 

 

---------------------------------------------------------------------------------------------------------

 

一致性哈希

首先,把任何輸入都進行hash得到哈希值爲0~2^64(當然也可以定義別的範圍),然後順時針方向從小到大組成一個圓環

然後後端服務器同樣是m1、m2、m3三臺服務器組成集羣,然後每臺機器都有一個唯一的編號,可以使用機器的ip地址、mac地址等其中的一個做每臺機器的唯一標識,例如我們使用機器的mac地址,然後進行hash(mac)得到一個哈希值,然後把機器放到該位置上因爲三個機器把整個圓均等分成了三份,故數據的存放也是均勻的,所以具有負載均衡的效果。

因此,m0、m1、m2哈希值是遞增的序列,這時,客戶端同樣是三條數據data1、data2、data3,經過前端負載服務器,然後把data1、data2、data3分別進行hash(data1)、hash(data2)和hash(data3)的操作,分別得到三個哈希值,接着按順時針方向找到最近的機器進行存儲。如圖,data1存放在m0,data2存放在m1,data3存放在m2上。

因此,由順時針法則,某數據的哈希值如果在紅色的區域,則存放在m0上,哈希值如果在綠色區域,則存放在m1上,哈希值如果在藍色區域,則存放在m2上。

每個前端負載服務器都有一個按後端服務器哈希值升序排好序的序列,例如每個前端負載服務器都有後端三個按哈希值升序排好序的機器[m1,m3,m2],每當數據來到前端負載服務器時,計算該數據的哈希值,然後從排好序的機器序列中找到第一個比該數據哈希值大的數,就把該數據存到該機器上。該部分可使用二分法進行查找。即使機器很多,但是代價查找只有logn

例如有三臺機器m1、m2、m3,它們的哈希值分別是1、5、3,所有按升序排序後的結果如圖。

有一個數據data經過前端負載服務器得到hash值爲4,然後在[1,3,5]中找到第一個比4大的數,即爲5,所以該數據應該存放在哈希值爲5對應的機器m2上。

-----------------------------------------------------------------------------------------------------------------

 

一致性哈希數據遷移問題

假設原來的後端服務器集羣只有m1、m2、m3三臺機器。

hash值在綠色區間這段的數據存放在m1上,此時加多了一臺m3機器,計算hash值後得到的值在m0和m1之間。

因此,按順時針原則,只需要把哈希值在m0和m3之間的存放在m1上的數據遷移到m3即可。因此數據遷移的代價減少了。

----------------------------------------------------------------------------------------------------------------

 

更多幹貨,請掃碼關注「IT界的泥石流微信公衆號哦,帶你領略編程之美!