淺嘗一致性Hash原理

寫在前面

  在解決分佈式系統中負載均衡的問題時候可使用Hash算法讓固定的一部分請求落到同一臺服務器上,這樣每臺服務器固定處理一部分請求(並維護這些請求的信息),起到負載均衡的做用。可是普通的餘數hash(hash(好比用戶id)%服務器機器數)算法伸縮性不好,當新增或者下線服務器機器時候,用戶id與服務器的映射關係會大量失效。一致性hash則利用hash環對其進行了改進。算法

一致性Hash概述

  爲了能直觀的理解一致性hash原理,這裏結合一個簡單的例子來說解,假設有4臺服務器,地址爲ip1,ip2,ip3,ip4。服務器

  一致性hash是首先計算四個ip地址對應的hash值
    hash(ip1),hash(ip2),hash(ip3),hash(ip3),計算出來的hash值是0~最大正整數直接的一個值,這四個值在一致性hash環上呈現以下圖:負載均衡

  • hash環上順時針從整數0開始,一直到最大正整數,咱們根據四個ip計算的hash值確定會落到這個hash環上的某一個點,至此咱們把服務器的四個ip映射到了一致性hash環
  • 當用戶在客戶端進行請求時候,首先根據hash(用戶id)計算路由規則(hash值),而後看hash值落到了hash環的那個地方,根據hash值在hash環上的位置順時針找距離最近的ip做爲路由ip.

  如上圖可知user1,user2的請求會落到服務器ip2進行處理,User3的請求會落到服務器ip3進行處理,user4的請求會落到服務器ip4進行處理,user5,user6的請求會落到服務器ip1進行處理。分佈式

  下面考慮當ip2的服務器掛了的時候會出現什麼狀況?當ip2的服務器掛了的時候,一致性hash環大體以下圖:
3d

  根據順時針規則可知user1,user2的請求會被服務器ip3進行處理,而其它用戶的請求對應的處理服務器不變,也就是隻有以前被ip2處理的一部分用戶的映射關係被破壞了,而且其負責處理的請求被順時針下一個節點委託處理。blog

  下面考慮當新增機器的時候會出現什麼狀況?當新增一個ip5的服務器後,一致性hash環大體以下圖:ip

   根據順時針規則可知以前user1的請求應該被ip1服務器處理,如今被新增的ip5服務器處理,其餘用戶的請求處理服務器不變,也就是新增的服務器順時針最近的服務器的一部分請求會被新增的服務器所替代。ci

 

一致性hash的特性

  • 單調性(Monotonicity),單調性是指若是已經有一些請求經過哈希分派到了相應的服務器進行處理,又有新的服務器加入到系統中時候,應保證原有的請求能夠被映射到原有的或者新的服務器中去,而不會被映射到原來的其它服務器上去。 這個經過上面新增服務器ip5能夠證實,新增ip5後,原來被ip1處理的user6如今仍是被ip1處理,原來被ip1處理的user5如今被新增的ip5處理。
  • 分散性(Spread):分佈式環境中,客戶端請求時候可能不知道全部服務器的存在,可能只知道其中一部分服務器,在客戶端看來他看到的部分服務器會造成一個完整的hash環。若是多個客戶端都把部分服務器做爲一個完整hash環,那麼可能會致使,同一個用戶的請求被路由到不一樣的服務器進行處理。這種狀況顯然是應該避免的,由於它不能保證同一個用戶的請求落到同一個服務器。所謂分散性是指上述狀況發生的嚴重程度。好的哈希算法應儘可能避免儘可能下降分散性。 一致性hash具備很低的分散性
  • 平衡性(Balance):平衡性也就是說負載均衡,是指客戶端hash後的請求應該可以分散到不一樣的服務器上去。一致性hash能夠作到每一個服務器都進行處理請求,可是不能保證每一個服務器處理的請求的數量大體相同,以下圖

  服務器ip1,ip2,ip3通過hash後落到了一致性hash環上,從圖中hash值分佈可知ip1會負責處理大概80%的請求,而ip2和ip3則只會負責處理大概20%的請求,雖然三個機器都在處理請求,可是明顯每一個機器的負載不均衡,這樣稱爲一致性hash的傾斜,虛擬節點的出現就是爲了解決這個問題。路由

虛擬節點

  當服務器節點比較少的時候會出現上節所說的一致性hash傾斜的問題,一個解決方法是多加機器,可是加機器是有成本的,那麼就加虛擬節點,好比上面三個機器,每一個機器引入1個虛擬節點後的一致性hash環的圖以下:hash

  其中ip1-1是ip1的虛擬節點,ip2-1是ip2的虛擬節點,ip3-1是ip3的虛擬節點。可知當物理機器數目爲M,虛擬節點爲N的時候,實際hash環上節點個數爲M*N。好比當客戶端計算的hash值處於ip2和ip3或者處於ip2-1和ip3-1之間時候使用ip3服務器進行處理。

均勻一致性hash

  上節咱們使用虛擬節點後的圖看起來比較均衡,可是若是生成虛擬節點的算法不夠好極可能會獲得下面的環:

  可知每一個服務節點引入1個虛擬節點後,狀況相比沒有引入前均衡性有所改善,可是並不均衡。均衡的一致性hash應該是以下圖:

  均勻一致性hash的目標是若是服務器有N臺,客戶端的hash值有M個,那麼每一個服務器應該處理大概M/N個用戶的。也就是每臺服務器負載儘可能均衡

相關文章
相關標籤/搜索