參照:http://www.javashuo.com/article/p-ujqsbcvn-by.htmlhtml
參照:http://www.cnblogs.com/haippy/archive/2011/12/10/2282943.html前端
如下內容,僅供本身理解複習,表達能力有限,還請您見諒!數組
hash一致性解決的問題:如經典的服務器負載均衡,在前端經過一個相同的hash函數計算出一個數值,取模總服務器數,而後把請求分發到相對應的服務器上,依次實現負載均衡。可是若是忽然之間,流量增大,那麼就會出現服務器數量要擴容的狀況,這樣的代價很大,須要從新計算出新的hash,遷移各服務器上的數據。hash一致性正是用來解決這個問題,花少許的代價。服務器
首先咱們拋棄原始的hash取模找服務器,而是把hash函數算出來的值用一個抽象的環來表示。假設hash值的範圍是0~2^64-1。而後把服務器映射上去,那麼每次數據key經過相同的hash算出來一個值,也映射到環上,順時針查找離服務器最近的點,該服務器就存儲着對應的數據,就能夠查到了。具體的查找服務器,固然不是遍歷,那太耗時了,由於這個每臺服務器的hash值用一個有序數組存儲起來(大於等於,最右邊的),因此能夠經過二分的方法來肯定相應的最近服務器。負載均衡
再分析加機器的代價,若是用hash一致性的話,那麼每次只須要把前一臺服務器對應的環上在其後面的數據給遷移進新加的服務器便可。減服務器,同理,只需把這臺服務器的數據轉移到環上的後面一臺服務器上便可。函數
這也迎來了兩個問題,其一若是服務器數量很是的少,假設只有三臺,那麼hash函數的機率平均性就很難體現出來了,可能出現三臺服務器在環山的距離很近。那麼負載就不均衡了,可能某一臺服務器要處理90%的數據處理,而其他兩臺只需分擔10%的數據處理。這就很難受了。其二,若是這三臺服務器恰好負載均衡,那麼再加一臺服務器的時候就又不負載均衡了。解決的方法,就是引出一個新的概念,虛擬節點,每臺服務器給分配(假設1000個虛擬節點)。每個虛擬節點都在hash環上佔一個值,可是這些虛擬節點對應哪臺服務器,就去哪臺服務器上找數據。這樣就把hash環給均衡了,真的很美妙。htm
以上所描述的就是一致性hash。把握一下幾點:1.拋棄hash取模,而是把hash值拿出來,造成一個環。2.把服務器映射到環上,順時針找最近的服務器。3.虛擬節點,不把服務器映射上去了,而是把服務器對應的虛擬節點映射上去,用一個路由表記錄相應的虛擬節點對應的服務器。這樣虛擬節點就徹底把hash值相均衡化了,依此,實現負載均衡。blog