一致性哈希機器在分佈式中的作用

哈希算法是根據hash值將不同的value映射到相應的位置的過程。

那麼在分佈式中,【比如memcached】,需要將不同的緩存對象按照相應的hash算法映射到相應的機器上去,那麼當添加一臺機器或者是其中某一臺機器宕機之後,如果按照最原始的key%n的形式來做hash的話,需要將緩存清空,然後重新將內容映射到所有的機器上,這樣的代價是巨大的。

於是粗線了一致性哈希。簡單來說,一致性哈希將整個哈希值空間組織成一個虛擬的圓環,如假設某哈希函數H的值空間爲0~2^32-1,如下圖所示:

整個空間按順時針方向組織。0和232-1在零點中方向重合。

下一步將服務器使用H【hash算法】進行哈希(具體可以選擇服務器的ip或主機名作爲關鍵字進行哈希),映射到哈希環上的某個位置,這裏假設將三臺服務器使用ip地址哈希後在環空間的位置如下

1349781404_3472.png

服務器佈置好之後,就要映射數據了。

使用如下算法映射數據到相應服務器:將數據key使用相同的函數H【hash算法】計算出哈希值h【根據h確定此數據在環上的位置】。從此位置沿環順時針“行走”,第一臺遇到的服務器就是其應該映射到的服務器。

例如我們有A、B、C、D四個數據對象,經過哈希計算後,在環空間上的位置如下:

1349781518_6489.png

根據一致性哈希算法,數據A會被定爲到Server 1上,D被定爲到Server 3上,而B、C分別被定爲到Server 2上。

------------------------------------------混個混個----------------------------------------------

上面是講一致性哈希的服務器佈置和key-value的映射過程。

下面說一致性哈希的擴展性和容錯性。

現假設Server 3宕機了:

1349781638_5744.png

可以看到此時A、C、B不會受到影響,只有D節點被重定位到Server 2【這在分佈式中是很好定位的,比如說server3宕機了,那麼根據一致性哈希算反,查找的時候,會發現D在server2上,但是在server3剛剛宕機的時候,server2上並沒有D,此時應用會把數據緩存到server2上,此時,D就被hash到server2上了】。

下面考慮另外一種情況,如果我們在系統中增加一臺服務器Memcached Server 4:

1349781817_7613.png

此時,B不會去server2查找數據了,而會在server4上查找,如果B此時不存在於server4上,那麼會緩存從數據庫取回來的B在server4上。而server2上的數據,會因爲時間太久沒有被訪問或者是因爲超時而被memcached清理掉了。綜上所述,一致性哈希算法對於節點的增減都只需重定位環空間中的一小部分數據,具有較好的容錯性和可擴展性。

一致性哈希的缺點

當然,萬物都是有兩面性的。

一致性哈希算法在服務節點太少時,容易因爲節點分部不均勻而造成數據傾斜問題。例如我們的系統中有兩臺服務器,其環分佈如下:

1349781953_4428.png

那麼此時數據大部分會存到server1中,而2中會因爲距離1太近而有很少的數據。爲了解決這種數據傾斜問題,一致性哈希算法引入了虛擬節點機制,即對每一個服務節點計算多個哈希【具體可以這麼做:根據服務器的名字或者是ip計算節點hash的時候,可以加上編號,然後再計算哈希值】,在每個計算的結果位置都放置一個服務節點,稱爲虛擬節點。這樣,數據再被存儲的時候,就不會因爲服務器在環上的間距太大而導致“數據傾斜”了。

至於Memcached 的分佈式,則完全由客戶端實現。這種分佈式是Memcached最大的特點。

目前一致性哈希是分佈式的標準配置。


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