的一致性雜湊 一致性雜湊演算法詳解及PHP實現

2021-10-16 03:31:06 字數 3341 閱讀 6265

在維基百科中,一致性雜湊是這麼定義的:

一致雜湊是一種特殊的雜湊演算法。在使用一致雜湊演算法後,雜湊表槽位數(大小)的改變平均只需要對 k/n個關鍵字重新對映,其中k是關鍵字的數量, n是槽位數量。然而在傳統的雜湊表中,新增或刪除乙個槽位的幾乎需要對所有關鍵字進行重新對映。
我們從定義中看到一致性hash演算法的基本優勢,我們看到了該演算法主要解決的問題是:當slot數發生變化時,能夠盡量少的移動資料。那麼,我們思考一下,普通的hash演算法是如何實現?又存在什麼問題呢?

假設有這樣乙個問題,我們有三個節點,將一批資料均勻的分散到這三個節點上,一般的雜湊演算法我們會這麼做:

這種雜湊演算法,重度依賴於節點的個數,即當node數發生變化(增加、移除)後,資料項會被重新「打散」,導致大部分資料項不能落到原來的節點上,從而導致大量資料需要遷移。想象一下,這種缺陷幾乎是我們不能接受的。

那麼,乙個亟待解決的問題就變成了:當node數發生變化時,如何保證盡量少引起遷移呢?即當增加或者刪除節點時,對於大多數item,保證原來分配到的某個node,現在仍然應該分配到那個node,將資料遷移量的降到最低。因此該一致性雜湊演算法登場了。

一致性雜湊演算法

一致性雜湊演算法的大致原理是這樣的,通過乙個叫作一致性hash環的資料結構實現。這個環的起點是0,終點是2^32 - 1,並且起點與終點連線,環的中間的整數按逆時針分布,故這個環的整數分布範圍是[0, 2^32-1],如圖所示:

注意一致性雜湊演算法並不是完全避免了增刪節點時的資料遷移,而是把需要遷移的資料降到最小,特別是相比簡單取模的雜湊演算法。

假入我們有乙個空的雜湊環如圖所示那麼從0 - 2^32-1會如圖所示:

將物件放到雜湊環上

假設現在我們有4個物件,分別為o1,o2,o3,o4,使用hash函式計算這4個物件的hash值(範圍為0 ~ 2^32-1): hash(ox) = mx,把m1,m2,m3,m4 這4個值放置到hash環上,得到下圖:

將機器放到雜湊環上

使用同樣的hash函式,我們將機器也放置到hash環上。假設我們有三颱快取機器,分別為 c1,c2,c3,使用hash函式計算這3臺機器的hash值:hash(cx) = tx把t1,t2,t3 這3個值放置到hash環上,得到下圖:

將物件和機器都放置到同乙個hash環後,在hash環上順時針查詢距離這個物件的hash值最近的機器,即是這個物件所屬的機器。 例如, 對於物件o2, 順序針找到最近的機器是c1,故機器c1會快取物件o2。而機器c2則快取o3、o4, 機器c3則快取物件o1。如圖所示:

處理機器增減的情況

對於線上的業務,增加或者減少一台機器的部署是常有的事情。 例如,增加機器c4的部署並將機器c4加入到hash環的機器c3與c2之間。這時,只有機器c3與c4之間的物件需要重新分配新的機器。對於我們的例子,只有物件o4被重新分配到了c4,其他物件仍在原有機器上。如圖所示:

如上文前面所述,使用簡單的求模方法,當新新增機器後會導致大部分快取失效的情況,使用一致性hash演算法後這種情況則會得到大大的改善。前面提到3臺機器變成4臺機器後,快取命中率只有25%(不命中率75%)。而使用一致性hash演算法,理想情況下快取命中率則有75%,而且,隨著機器規模的增加,命中率會進一步提高,99臺機器增加一台後,命中率達到99%,這大大減輕了增加快取機器帶來的資料庫訪問的壓力。

再例如,將機器c1下線(當然,也有可能是機器c1宕機),這時,只有原有被分配到機器c1物件需要被重新分配到新的機器。對於我們的例子,只有物件o2被重新分配到機器c3,其他物件仍在原有機器上。如圖所示:

虛擬節點

上面提到的過程基本上就是一致性hash的基本原理了,不過還有乙個小小的問題。新加入的機器c4只分擔了機器c2的負載,機器c1與c3的負載並沒有因為機器c4的加入而減少負載壓力。如果4臺機器的效能是一樣的,那麼這種結果並不是我們想要的。 為此,我們引入虛擬節點來解決負載不均衡的問題。

將每台物理機器虛擬為一組虛擬機器,將虛擬機器放置到hash環上,如果需要確定物件的機器,先確定物件的虛擬機器,再由虛擬機器確定物理機器。

說得有點複雜,其實過程也很簡單。

還是使用上面的例子,假如開始時存在快取機器c1,c2,c3,對於每個快取機器,都有3個虛擬節點對應,其一致性hash環結構如圖所示:

假設對於物件o1,其對應的虛擬節點為c11,而虛擬節點c11物件快取機器c1,故物件o1被分配到機器c1中。

新加入快取機器c4,其對應的虛擬節點為c41,c42,c43,將這三個虛擬節點新增到hash環中,得到的hash環結構如圖所示:

新加入的快取機器c4對應一組虛擬節點c41,c42,c43,加入到hash環後,影響的虛擬節點包括c31,c22,c11(順時針查詢到第乙個節點),而這3個虛擬節點分別對應機器c3,c2,c1。即新加入的一台機器,同時影響到原有的3臺機器。理想情況下,新加入的機器平等地分擔了原有機器的負載,這正是虛擬節點帶來的好處。而且新加入機器c4後,只影響25%(1/4)物件分配,也就是說,命中率仍然有75%,這跟沒有使用虛擬節點的一致性hash演算法得到的結果是相同的。

總結

一致性hash演算法解決了分布式環境下機器增加或者減少時,簡單的取模運算無法獲取較高命中率的問題。通過虛擬節點的使用,一致性hash演算法可以均勻分擔機器的負載,使得這一演算法更具現實的意義。正因如此,一致性hash演算法被廣泛應用於分布式系統中。

最後我們給出一種php語言的實現:

一致性雜湊

直接貼出一篇介紹的很清楚的博文。關鍵字一致性雜湊 平衡性,單調性,分散性,負載 其實說白了,就是解決把請求分散到不同的機器上運算,怎麼做分散的平均,機器少一台多一台,或者壞掉一台,成很好的自適應和拓展。最簡單的實現分布式演算法,取模嘛,但是它就上述的一些問題,所以不算好的雜湊函式。一致性雜湊演算法,...

一致性雜湊

from 學習分布式,一致性雜湊是最最基礎的知識,所以要理解好.那什麼是一致性雜湊呢?what 1.平衡性是指 hash的結果應該平均分配到各個節點,這樣從演算法上就解決了負載均衡問題.2.單調性是指 在新增或者刪減節點時,同乙個key訪問到的值總是一樣的.3.分散性是指 資料應該分散的存放在 分布...

一致性雜湊

一致性 雜湊演算法在1997年由 麻省理工學院提出 參見擴充套件閱讀 1 設計目標是為了解決網際網路中的熱點 hot spot 問題,初衷和 carp十分類似。一致性雜湊修正了carp使用的簡單雜湊演算法帶來的問題,使得dht可以在p2p環境中真正得到應用。雜湊演算法 編輯 一致性雜湊提出了在動態變...