背景
一致性哈希算法在1997年由麻省理工學院的Karger等人在解決分佈式Cache中提出的,設計目標是爲了解決因特網中的熱點(Hot spot)問題,初衷和CARP十分類似。一致性哈希修正了CARP使用的簡單哈希算法帶來的問題,使得DHT可以在P2P環境中真正得到應用。
但現在一致性hash算法在分佈式系統中也得到了廣泛應用,研究過memcached緩存數據庫的人都知道,memcached服務器端本身不提供分佈式cache的一致性,而是由客戶端來提供,具體在計算一致性hash時採用如下步驟:
- 首先求出memcached服務器(節點)的哈希值,並將其配置到0~232的圓(continuum)上。
- 然後採用同樣的方法求出存儲數據的鍵的哈希值,並映射到相同的圓上。
- 然後從數據映射到的位置開始順時針查找,將數據保存到找到的第一個服務器上。如果超過232仍然找不到服務器,就會保存到第一臺memcached服務器上。
好的hash算法特點
- 平衡性(Balance)
平衡性是指哈希的結果能夠儘可能分佈到所有的緩衝中去,這樣可以使得所有的緩衝空間都得到利用。很多哈希算法都能夠滿足這一條件。
- 單調性(Monotonicity)
單調性是指如果已經有一些內容通過哈希分派到了相應的緩衝中,又有新的緩衝區加入到系統中,那麼哈希的結果應能夠保證原有已分配的內容可以
被映射到新的緩衝區中去,而不會被映射到舊的緩衝集合中的其他緩衝區。簡單的哈希算法往往不能滿足單調性的要求,如最簡單的線性哈希:
x = (ax + b) mod (P),在上式中,P表示全部緩衝的大小。不難看出,當緩衝大小發生變化時(從P1到P2),原來所有的哈希結果均會發生變化,從而
不滿足單調性的要求。哈希結果的變化意味着當緩衝空間發生變化時,所有的映射關係需要在系統內全部更新。而在P2P系統內,緩衝的變化等價於
Peer加入或退出系統,這一情況在P2P系統中會頻繁發生,因此會帶來極大計算和傳輸負荷。單調性就是要求哈希算法能夠應對這種情況。
- 分散性(Spread)
在分佈式環境中,終端有可能看不到所有的緩衝,而是隻能看到其中的一部分。當終端希望通過哈希過程將內容映射到緩衝上時,由於不同終端
所見的緩衝範圍有可能不同,從而導致哈希的結果不一致,最終的結果是相同的內容被不同的終端映射到不同的緩衝區中。這種情況顯然是應該避免
的,因爲它導致相同內容被存儲到不同緩衝中去,降低了系統存儲的效率。分散性的定義就是上述情況發生的嚴重程度。好的哈希算法應能夠儘量避免
不一致的情況發生,也就是儘量降低分散性。
- 負載(Load)
負載問題實際上是從另一個角度看待分散性問題。既然不同的終端可能將相同的內容映射到不同的緩衝區中,那麼對於一個特定的緩衝區而言,
也可能被不同的用戶映射爲不同的內容。與分散性一樣,這種情況也是應當避免的,因此好的哈希算法應能夠儘量降低緩衝的負荷。
- 平滑性(Smoothness)
平滑性是指緩存服務器的數目平滑改變和緩存對象的平滑改變是一致的。
實現原理
整個空間按順時針方向組織。0和232-1在零點中方向重合。下一步將各個服務器使用Hash進行一個哈希,具體可以選擇服務器的ip或主機
名作爲關鍵字進行哈希,這樣每臺機器就能確定其在哈希環上的位置,這裏假設將上文中四臺服務器使用ip地址哈希後在環空間的
位置如下:
接下來使用如下算法定位數據訪問到相應服務器:將數據key使用相同的函數Hash計算出哈希值,並確定此數據在環上的位置,
從此位置沿環順時針“行走”,第一臺遇到的服務器就是其應該定位到的服務器。
例如我們有Object A、Object B、Object C、Object D四個數據對象,經過哈希計算後,在環空間上的位置如下:
根據一致性哈希算法,數據A會被定爲到Node A上,B被定爲到Node B上,C被定爲到Node C上,D被定爲到Node D上。
下面分析一致性哈希算法的容錯性和可擴展性。現假設Node C不幸宕機,可以看到此時對象A、B、D不會受到影響,只有C對象被重定位
到Node D。一般的,在一致性哈希算法中,如果一臺服務器不可用,則受影響的數據僅僅是此服務器到其環空間中前一臺服務器(即沿着
逆時針方向行走遇到的第一臺服務器)之間數據,其它不會受到影響。
下面考慮另外一種情況,如果在系統中增加一臺服務器Node X,如下圖所示:
此時對象Object A、B、D不受影響,只有對象C需要重定位到新的Node X 。一般的,在一致性哈希算法中,如果增加一臺服務器,
則受影響的數據僅僅是新服務器到其環空間中前一臺服務器(即沿着逆時針方向行走遇到的第一臺服務器)之間數據,其它數據也不會受到影響。
綜上所述,一致性哈希算法對於節點的增減都只需重定位環空間中的一小部分數據,具有較好的容錯性和可擴展性。
另外,一致性哈希算法在服務節點太少時,容易因爲節點分部不均勻而造成數據傾斜問題。例如系統中只有兩臺服務器,其環分佈如下