一致性HASH(雜湊)演算法

2021-09-24 22:06:22 字數 3019 閱讀 6635

在了解一致性雜湊演算法之前,讓我們先了解一下雜湊演算法。

在現在大規模集群應用中,快取是必不可少的乙個標準開發配置。當快取應用越來越多,越多越大,會應運而生分布式快取系統。

那我們的快取資料(k-v)如何均勻的分散到集群中呢?

相關的演算法有很多,如:輪循演算法(round robin)、雜湊演算法(hash)、最少連線演算法(least connection)、響應速度演算法(response time)、加權法(weighted )等。其中雜湊演算法是最為常用的演算法。

最典型的場景如下:

有n臺伺服器提供快取服務,需要對伺服器進行負載均衡,將請求平均分發到每台伺服器上,每台機器負責1/n的服務。

常用的演算法是對hash結果取餘數 (hash() mod n ):對機器編號從0到n-1,按照自定義的 hash()演算法,對每個請求的hash()值按n取模,得到餘數i,然後將請求分發到編號為i的機器。

但是這種做法,有個很致命的問題。如果某一台機器宕機,那麼應該落在該機器的請求就無法得到正確的處理,這時需要將當掉的伺服器從演算法從去除,此時候會有(n-1)/n的伺服器的快取資料需要重新進行計算;如果新增一台機器,會有n /(n+1)的伺服器的快取資料需要進行重新計算。如下面兩張圖所示:

對於系統而言,這通常是不可接受的(因為這意味著大量快取的失效或者資料需要轉移),因為它沒有考慮容錯性和擴充套件性。

所謂容錯性是指當系統中某乙個或幾個伺服器變得不可用時,整個系統是否可以正確高效執行;而擴充套件性是指當加入新的伺服器後,整個系統是否可以正確高效執行

那麼,如何設計乙個負載均衡策略,使得發生以上情況時,將我們受到影響盡可能的減少呢?

這就引入了我們要重點講述的一致性雜湊演算法。

那什麼是一致性雜湊演算法?

一致性雜湊演算法(consistent hashing algorithm)是一種分布式演算法,常用於負載均衡。

簡單來說,一致性雜湊將整個雜湊值空間組織成乙個虛擬的圓環,如假設某雜湊函式h的值空間為0 - (2^32)-1(即雜湊值是乙個32位無符號整形),整個雜湊空間環如下:

整個空間按順時針方向組織。0和(2^32)-1在零點中方向重合。

那一致性雜湊演算法在使用過程中,具體是如何操作的呢?

在我們思考如何將快取值(k-v)通過一致性雜湊演算法存在快取伺服器上之前,首先需要確定快取伺服器在雜湊環上的位置。

具體操作如下:

將各個伺服器使用h進行乙個雜湊,具體可以選擇伺服器的ip或主機名作為關鍵字進行雜湊,這樣每台機器就能確定其在雜湊環上的位置,這裡假設將三颱伺服器使用ip位址雜湊後在環空間的位置如下:

那麼接下來,如何定位我們的資料儲存位置呢?

將資料key使用相同的函式h計算出雜湊值h,通根據h確定此資料在環上的位置,從此位置沿環順時針「行走」,第一台遇到的伺服器就是其應該定位到的伺服器。

例如我們有a、b、c、d四個資料物件,經過雜湊計算後,在環空間上的位置如下:

根據一致性雜湊演算法,資料a會被定位到伺服器3上,d被定位到伺服器2上,而b、c分別被定位到伺服器1上。

既然說到了我們的雜湊演算法對容錯性和可擴充套件性的處理能力有限,那麼一致性雜湊演算法的表現如何呢?

現在假設伺服器3宕機了,如下所示:

可以看到資料b、c、d不會受到影響,只有a資料被重定位到伺服器1。一般的,在一致性雜湊演算法中,如果一台伺服器不可用,則受影響的資料僅僅是此伺服器到其環空間中前一台伺服器(即順著逆時針方向行走遇到的第一台伺服器)之間資料(a資料),其它不會受到影響。

下面,我們來看另外一種情況,假設,我們在系統中新增了一台伺服器4,如下所示:

此時資料a、c、d不受影響,只有資料b需要重定位到新的伺服器4。一般的,在一致性雜湊演算法中,如果增加一台伺服器,則受影響的資料僅僅是新伺服器到其環空間中前一台伺服器(即順著逆時針方向行走遇到的第一台伺服器)之間資料(b資料),其它不會受到影響。

那麼,我們的一致性雜湊演算法除了較好的解決了我們的容錯性和可擴充套件性,它還有什麼優點呢?

不知道大家有沒有發現乙個問題,如果使用一致性雜湊演算法,在服務節點太少時,因為節點分部不均勻很容易而造成資料傾斜問題。假如我們的系統中現在只有兩台伺服器,其環分布如下:

此時資料的儲存,必然會造成大量資料集中到伺服器1上,而只有極少量會定位到伺服器2上。

那為了解決這種資料傾斜問題,一致性雜湊演算法引入了虛擬節點機制。即對每乙個服務節點計算多個雜湊,每個計算結果位置都放置乙個此服務節點,稱為虛擬節點。

具體做法可以在伺服器ip或主機名的後面增加編號來實現。例如上面的情況,我們決定為每台伺服器計算三個虛擬節點,於是可以分別計算「伺服器1#1」、「伺服器1#2」、「伺服器1#3」、「伺服器2#1」、「伺服器2#2」、「伺服器2#3」的雜湊值,於是形成六個虛擬節點,具體如下:

這樣就能夠有效的解決我們因為服務節點過少而造成的資料傾斜問題。

一致性hash演算法 面試必備 一致性hash演算法

最近公司在招人,我們準備的問題中有一道是關於一致性hash演算法的問題,只有一些面試者能夠回答上來,而且答的也不是很全面,有的面試者只是聽說過,有的連聽都沒聽過,下面我把一致性hash演算法整理一下分享給大家 一致性雜湊演算法在1997年由麻省理工學院的karger等人在解決分布式cache中提出的...

一致性hash演算法虛擬節點 一致性hash演算法

hash 演算法也叫做雜湊演算法,他可以讓任意長度的資料m對映成為長度固定的值h。hash演算法的第乙個作用就是資料的快速儲存與查詢。寫過程式的人都知道,基本上主流的程式語言裡面都有個資料結構叫做map dictionary或者 hash table 它是根據key來直接訪問結果的資料結構。key的...

一致性hash演算法

july部落格16章開始 第一題 全排列,輸入乙個字串,列印出該字串中字元的所有排列 1.個人思路 回溯法建立的排序樹 2.july部落格 遞迴實現,依次固定第乙個字母,後面的交換,和上面描述的使用回溯法相似 c stl 演算法 next permutation的思想,關於next permutat...