在redis 集群模式cluster中,redis採用的是分片sharding的方式,也就是將資料採用一定的分割槽策略,分發到相應的集群節點中。但是我們使用上述hash演算法進行快取時,會出現一些缺陷,主要體現在伺服器數量變動的時候,所有快取的位置都要發生改變!具體來講就是說第一當快取伺服器數量發生變化時,會引起快取的雪崩,可能會引起整體系統壓力過大而崩潰(大量快取同一時間失效)。第二當快取伺服器數量發生變化時,幾乎所有快取的位置都會發生改變。
一致性hash演算法也是使用取模的方法,只是,剛才描述的取模法是對伺服器的數量進行取模,而一致性hash演算法是對232取模,什麼意思呢?簡單來說,一致性hash演算法將整個雜湊值空間組織成乙個虛擬的圓環,如假設某雜湊函式h的值空間為0-232-1(即雜湊值是乙個32位無符號整形),整個雜湊環如下:
整個空間按順時針方向組織,圓環的正上方的點代表0,0點右側的第乙個點代表1,以此類推,2、3、4、5、6……直到232-1,也就是說0點左側的第乙個點代表232-1, 0和232-1在零點中方向重合,我們把這個由232個點組成的圓環稱為hash環。
那麼,一致性雜湊演算法與上圖中的圓環有什麼關係呢?我們繼續聊,仍然以之前描述的場景為例,假設我們有4臺快取伺服器,伺服器a、伺服器b、伺服器c,伺服器d,那麼,在生產環境中,這4臺伺服器肯定有自己的ip位址或主機名,我們使用它們各自的ip位址或主機名作為關鍵字進行雜湊計算,使用雜湊後的結果對2^32取模,可以使用如下公式示意:
hash(伺服器a的ip位址) % 2^32
通過上述公式算出的結果一定是乙個0到232-1之間的乙個整數,我們就用算出的這個整數,代表伺服器a,既然這個整數肯定處於0到232-1之間,那麼,上圖中的hash環上必定有乙個點與這個整數對應,而我們剛才已經說明,使用這個整數代表伺服器a,那麼,伺服器a就可以對映到這個環上。
接下來使用如下演算法定位資料訪問到相應伺服器: 將資料key使用相同的函式hash計算出雜湊值,並確定此資料在環上的位置,從此位置沿環順時針「行走」,第一台遇到的伺服器就是其應該定位到的伺服器!
現假設node c不幸宕機,可以看到此時物件a、b、d不會受到影響,只有c物件被重定位到node d。一般的,在一致性hash演算法中,如果一台伺服器不可用,則受影響的資料僅僅是此伺服器到其環空間中前一台伺服器(即沿著逆時針方向行走遇到的第一台伺服器)之間資料,其它不會受到影響,如下所示:
下面考慮另外一種情況,如果在系統中增加一台伺服器node x,如下圖所示:
此時物件object a、b、d不受影響,只有物件c需要重定位到新的node x !一般的,在一致性hash演算法中,如果增加一台伺服器,則受影響的資料僅僅是新伺服器到其環空間中前一台伺服器(即沿著逆時針方向行走遇到的第一台伺服器)之間資料,其它資料也不會受到影響。
綜上所述,一致性hash演算法對於節點的增減都只需重定位環空間中的一小部分資料,具有較好的容錯性和可擴充套件性。
一致性hash演算法在服務節點太少時,容易因為節點分部不均勻而造成資料傾斜(被快取的物件大部分集中快取在某一台伺服器上)問題,例如系統中只有兩台伺服器,其環分布如下:
此時必然造成大量資料集中到node a上,而只有極少量會定位到node b上,從而出現hash環偏斜的情況,當hash環偏斜以後,快取往往會極度不均衡的分布在各伺服器上,如果想要均衡的將快取分布到2臺伺服器上,最好能讓這2臺伺服器盡量多的、均勻的出現在hash環上,但是,真實的伺服器資源只有2臺,我們怎樣憑空的讓它們多起來呢,沒錯,就是憑空的讓伺服器節點多起來,既然沒有多餘的真正的物理伺服器節點,我們就只能將現有的物理節點通過虛擬的方法複製出來。
這些由實際節點虛擬複製而來的節點被稱為"虛擬節點",即對每乙個服務節點計算多個雜湊,每個計算結果位置都放置乙個此服務節點,稱為虛擬節點。具體做法可以在伺服器ip或主機名的後面增加編號來實現。
例如上面的情況,可以為每台伺服器計算三個虛擬節點,於是可以分別計算 「node a#1」、「node a#2」、「node a#3」、「node b#1」、「node b#2」、「node b#3」的雜湊值,於是形成六個虛擬節點:
同時資料定位演算法不變,只是多了一步虛擬節點到實際節點的對映,例如定位到「node a#1」、「node a#2」、「node a#3」三個虛擬節點的資料均定位到node a上。這樣就解決了服務節點少時資料傾斜的問題。在實際應用中,通常將虛擬節點數設定為32甚至更大,因此即使很少的服務節點也能做到相對均勻的資料分布。
一致性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...