1. 程式人生 > >簡述一致性雜湊演算法

簡述一致性雜湊演算法

今天早上逛B站的時候首頁給我推薦了一個視訊,關於面試中一致性雜湊演算法的回答,好奇心驅使我點了進去。

時長:1小時半...

很納悶為什麼這個淺顯易懂的概念需要講這麼久,越來越多培訓機構的營銷號在發一些明明10分鐘解決的問題卻要將幾個小時的視訊,打上一些騙小白的標題,浪費幾個小時看完直接會自閉。

引入問題

我們先來看一個分散式快取的應用前景。

我們有三臺快取伺服器S0,S1,S2。

現在有3萬張圖片需要儲存到這三臺伺服器,最好能夠均勻的快取在伺服器上。
(可能有人要問了,直接平均分配S1放第一到一萬張...)

如果說我們以後還要新增快取伺服器呢?如果說以後還要新增圖片呢? 直接分配無異於直接定死了規則,以後擴充套件就是一個坑。

簡單的做法是對圖片進行雜湊演算法取值,把圖片名稱當作Key。

雜湊演算法有很多種,這個你暫時不理解也沒關係,它可以對一個Key進行計算獲得一個整數。

對於同一張圖片,我們進行雜湊之後得到的整數永遠是同一個,而不同圖片雜湊有可能是同一個整數(雜湊衝突)。

所以現在我們可以對圖片進行雜湊取值,得到的值對3取模,那麼每張圖片都可以得到一個0到2的整數,這就對應我們伺服器的編號。

流程如下:

這樣我們就可以把圖片隨機分配了,現在我們新來的圖片只需要雜湊取值之後再取模就可以知道放到哪個伺服器,因為圖片名稱是key,所以我們要找一個圖片也可以通過雜湊來找到存放在哪臺伺服器。

現在有一個問題是,如果說我們要新增一臺伺服器,那麼取模的值3需要變成4,而且之前儲存的圖片都需要重新計算進行改變。因為多了一臺伺服器,我們在找圖片的時候用了4取模來找,而在儲存時用的是3取模來儲存。

新加一臺伺服器會導致整個快取的修改,所以這種方法不適於新增伺服器。

一致性雜湊演算法

對於上面的問題,我們可以通過雜湊環來解決,這就是一致性雜湊演算法的核心了。

我們建立一個環,起始位置是0,終止位置是2的32次方。

對於三臺伺服器,我們對它們也進行雜湊求值(現在不需要取模了),通過雜湊我們得到它們在環上的位置。

得到伺服器的位置之後,我們可以再來對圖片進行雜湊取值拿到它們在環中的位置。

此時,如果我們要尋找圖片0儲存在哪個伺服器,就可以對圖片0先進行雜湊取值,得到它在環上的位置,從那個位置開始順時針遍歷,找到的第一臺伺服器就是它的儲存位置。

圖片0,圖片32在伺服器S0。

圖片9在伺服器S2。

這時如果我們要新新增一臺伺服器S3,可以先求得它的雜湊值找到在環上的位置。

假如說現在得到的時下圖位置。

此時圖片9的快取伺服器就會變成伺服器S3,而其它圖片不會有快取失效問題。

一致性雜湊演算法可以很大程度上解決新增伺服器之後快取失效的問題,它會用區域性失效來保證大部分快取能夠存活,對於圖片9這種失效的快取,就可以走正常的訪問路線,直接請求伺服器資料庫獲得圖片了。

最後

一致性雜湊演算法有一個坑,在我們運氣不好的情況下,可能三臺伺服器雜湊取值會非常接近。

這種情況下我們可以對三臺伺服器進行虛擬化,比如說把S0虛擬為S00,S01,S02,S03...把它們分佈在環上。

一致性雜湊在分散式快取中有很大作用,同樣面試也是常常問到,雖然說我們平常自己學習用不到(沒錢買這麼多伺服器),但是這種分散式演算法思想還是很有用的