在分佈式集羣中,對機器的添加刪除,或者機器故障後自動脫離集羣這些操做是分佈式集羣管理最基本的功能。若是採用經常使用的hash(object)%N算法,那麼在有機器添加或者刪除後,不少原有的數據就沒法找到了,這樣嚴重的違反了單調性原則。接下來主要講解一下一致性哈希算法是如何設計的:
按照經常使用的hash算法來將對應的key哈希到一個具備2^32次方個桶的空間中,即0~(2^32)-1的數字空間中。如今咱們能夠將這些數字頭尾相連,想象成一個閉合的環形。以下圖
如今咱們將object一、object二、object三、object4四個對象經過特定的Hash函數計算出對應的key值,而後散列到Hash環上。以下圖:
Hash(object1) = key1;
Hash(object2) = key2;
Hash(object3) = key3;
Hash(object4) = key4;
在採用一致性哈希算法的分佈式集羣中將新的機器加入,其原理是經過使用與對象存儲同樣的Hash算法將機器也映射到環中(通常狀況下對機器的hash計算是採用機器的IP或者機器惟一的別名做爲輸入值),而後以順時針的方向計算,將全部對象存儲到離本身最近的機器中。
假設如今有NODE1,NODE2,NODE3三臺機器,經過Hash算法獲得對應的KEY值,映射到環中,其示意圖以下:
Hash(NODE1) = KEY1;
Hash(NODE2) = KEY2;
Hash(NODE3) = KEY3;
經過上圖能夠看出對象與機器處於同一哈希空間中,這樣按順時針轉動object1存儲到了NODE1中,object3存儲到了NODE2中,object二、object4存儲到了NODE3中。在這樣的部署環境中,hash環是不會變動的,所以,經過算出對象的hash值就能快速的定位到對應的機器中,這樣就能找到對象真正的存儲位置了。
普通hash求餘算法最爲不妥的地方就是在有機器的添加或者刪除以後會照成大量的對象存儲位置失效,這樣就大大的不知足單調性了。下面來分析一下一致性哈希算法是如何處理的。
1. 節點(機器)的刪除
以上面的分佈爲例,若是NODE2出現故障被刪除了,那麼按照順時針遷移的方法,object3將會被遷移到NODE3中,這樣僅僅是object3的映射位置發生了變化,其它的對象沒有任何的改動。以下圖:
2. 節點(機器)的添加
若是往集羣中添加一個新的節點NODE4,經過對應的哈希算法獲得KEY4,並映射到環中,以下圖:
經過按順時針遷移的規則,那麼object2被遷移到了NODE4中,其它對象還保持這原有的存儲位置。經過對節點的添加和刪除的分析,一致性哈希算法在保持了單調性的同時,仍是數據的遷移達到了最小,這樣的算法對分佈式集羣來講是很是合適的,避免了大量數據遷移,減少了服務器的的壓力。
根據上面的圖解分析,一致性哈希算法知足了單調性和負載均衡的特性以及通常hash算法的分散性,但這還並不能當作其被普遍應用的起因,由於還缺乏了平衡性。下面將分析一致性哈希算法是如何知足平衡性的。hash算法是不保證平衡的,如上面只部署了NODE1和NODE3的狀況(NODE2被刪除的圖),object1存儲到了NODE1中,而object二、object三、object4都存儲到了NODE3中,這樣就照成了很是不平衡的狀態。在一致性哈希算法中,爲了儘量的知足平衡性,其引入了虛擬節點。
——「虛擬節點」( virtual node )是實際節點(機器)在 hash 空間的複製品( replica ),一實際個節點(機器)對應了若干個「虛擬節點」,這個對應個數也成爲「複製個數」,「虛擬節點」在 hash 空間中以hash值排列。
以上面只部署了NODE1和NODE3的狀況(NODE2被刪除的圖)爲例,以前的對象在機器上的分佈很不均衡,如今咱們以2個副本(複製個數)爲例,這樣整個hash環中就存在了4個虛擬節點,最後對象映射的關係圖以下:
根據上圖可知對象的映射關係:object1->NODE1-1,object2->NODE1-2,object3->NODE3-2,object4->NODE3-1。經過虛擬節點的引入,對象的分佈就比較均衡了。那麼在實際操做中,正真的對象查詢是如何工做的呢?對象從hash到虛擬節點到實際節點的轉換以下圖:
「虛擬節點」的hash計算能夠採用對應節點的IP地址加數字後綴的方式。例如假設NODE1的IP地址爲192.168.1.100。引入「虛擬節點」前,計算 cache A 的 hash 值:
Hash(「192.168.1.100」);
引入「虛擬節點」後,計算「虛擬節」點NODE1-1和NODE1-2的hash值:
Hash(「192.168.1.100#1」); // NODE1-1
Hash(「192.168.1.100#2」); // NODE1-2
引入虛擬節點,主要在於,若是一臺服務器掛了,可以將壓力引流至不一樣的服務器。
總結:一致性hash算法(DHT)經過減小影響範圍的方式解決了增減服務器致使的數據散列問題,從而解決了分佈式環境下負載均衡問題,若是存在熱點數據,那麼經過增添節點的方式,對熱點區間進行劃分,將壓力分配至其餘服務器。從新達到負載均衡的狀態。
參考: