用hash做緩存,假如有三臺服務器,1,2,3,有三萬張圖片,我想將圖片平均緩存到我三臺服務器上,一個服務器大概一萬張,怎么去實現這個辦法呢,可以用hash來取余數進行操作,加入我們是以圖片的名字作為key進行hash計算,hash (圖片名稱)%N 其中N為我們服務器的個數,我們將hash(圖片名稱)這一部分進行計算后得到的是一個正數,然后除以服務器的數目進行取余數,結果將會是0,1,2三個數,對應我們的服務器的編號,當我們作為客戶端去請求圖片的時候,圖片已經進行過hash運算了,直接找到對應服務器的編號進行圖片的訪問,這樣解決了我需要遍歷所有的服務器進行查找。
那如果我緩存的服務器的數量減少或者增加,如果還是按照原來的算法走,必定會造成緩存數據的丟失,會去向后端的服務器去請求,如果有一臺緩存服務器發生了故障,那我原來緩存的位置必定會發生改變,原來本該運算后要進行緩存到某一臺服務器的圖片,現在找不到對應緩存服務器,肯定會發生緩存的雪崩
所以出現了一致性hash算法相當于將服務器和圖片分別hash到我的hash環上進行就近緩存,hash環就是對2^32次方進行取模,從0開始一直到2^32,均勻分布在一個圓環(一個比方),0的順時針方向的第一位為1,逆時針方向第一位為2^32,大概如下圖
具體就是比方我有三個服務器A,B ,C對其進行 hash (服務器Aip)%2^32 得出來的一定是一個整數,而且一定是在0--2^32之間,那么這個數就會分布在hash環上對應的位置,相同的B,C都一樣,假設我們hash過后ABC的位置如下圖
然后我們將需要緩存圖片的key進行hash,它的hash值也會分布在我的hash環上,
如上圖,我hash到了A和C之間,圖片的存儲規則是順時針方向的存儲,所以應該存儲到A,如果有四張的話如下圖
那如果我們的hash算法將服務器和hash的圖片存放位置比較相近,類似于;
所有的緩存都集中存儲到了A一臺,只有5到了B,那么這樣A的壓力就不言而喻,沒有均勻可言了,辛虧hash環可以添加緩存服務器的虛擬節點,類似于虛擬機,一臺實機可以虛擬多臺,類似于這樣:
這樣的話就會盡可能的把緩存都均衡放在各個服務器
一致性hash算法的優勢在哪:一個是當我有一臺緩存節點掛了之后,緩存的存儲不會受太大的影響,
我們將b節點拿走,本來要在B節點存儲的3,因為找不到B服務器,而遵循規則緩存到C,而4的緩存節點不會發生改變,這就是一致hash的優點,如果發生服務器的增加或者減少只有部分的緩存會失效,不造成全盤皆輸的可能
一致hash到此結束。