一致性hash算法


背景

當我們的業務系統大到一定程度的時候,一台緩存服務器顯然不能滿足需求,需要使用多台緩存服務器。然后緩存服務器具體一定的用戶粘性屬性,如何設計緩存服務器使其命中率提高,並具有伸縮性。

普通余數hash

根據某個字段進行取模運算,根據余數值來選擇緩存服務器

該方式在擴展時存在問題,從5台服務器增加到6台,mod變成6,運算可以得出,之前的余數值全部失效,這樣設計就不具有用戶粘性了,在緩存大量失效的情況下,數據庫的壓力就會激增,可能導致數據庫宕機或業務中斷。

一致性hash

一致性hash算法通過一致性hash環來實現,先構造一個長度為0~2的32次方的整數環,再根據hash算法將緩存服務器映射到這個hash環上。當用戶來查詢時,將用戶特征同樣通過hash算法映射到hash環上,然后順時針查詢離這個key最近的緩存服務器節點。

當需要增加緩存服務器的時候,只需要將新的緩存服務器映射到hash環上,影響范圍很小,如下圖所示,新加入NODE3節點,NODE0節點和NODE2節點不受影響,理論上NODE3節點只分擔了NODE1節點50%的流量。

理論上上述請求的命中率是100% - 33% * 50% = 83.5%,且緩存服務器越多,新加入服務器后命中的概率越高。

 但是上述算法也存在一定的問題,NODE3節點的加入只分擔了NODE1的流量,這就相當於NODE0和NODE1節點的壓力是NODE1和NODE3的兩倍,如何做到負載均衡?

負載不均問題

 計算機領域有句話,計算機的任何問題都可以通過增加一個虛擬層來解決。計算機硬件、計算機網絡、計算機軟件都是如此。計算機網絡的7層協議,每一層都是下一層的虛擬層;計算機操作系統可以看做計算機硬件的虛擬層;jvm可以看做是操作系統的虛擬層;分層的計算機軟件架構也是利用虛擬層的概念。

解決一致性hash的負載不均問題,也可以利用虛擬層的概念,將每台物理緩存服務器虛擬成一組虛擬緩存服務器,再將虛擬的hash值放在hash環上。每次查詢時,先找到虛擬的緩存服務器key值,再通過該值找到物理服務器信息。

這樣新加入緩存服務器時,是加入一組虛擬服務器,如果數量足夠多的話,這個新加入的緩存服務器會均勻的影響原有的緩存服務器。

 

 

每個物理節點對應的虛擬節點越多,各個物理節點之間負載就越均衡,新加入的物理服務器對原有的物理服務器影響越保持一致(這就是一致性hash的名稱的由來)。

在實踐中,一台物理服務器虛擬多少虛擬服務器比較合適呢,太多會影響性能,太少又會負載不均衡,一般來說,經驗值是150,但是也要根提業務和情況來定。

 

分布式緩存實踐中,一致性hash是一個比較成熟的算法,不過還有其他優秀的算法,例如redis cluster的hash slot算法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM