一致性哈希虛擬節點


采用固定哈希算法平衡負載

在大規模的緩存應用中,應運而生了分布式緩存系統。key-value如何均勻的分散到集群中?最常規的方式莫過於hash取模的方式。比如集群中可用機器適量為N,那么key值為K的的數據請求很簡單的應該路由到hash(K) mod N對應的機器。但是在一些高速發展的web系統中,這樣的解決方案仍有些缺陷。隨着系統訪問壓力的增長,緩存系統不得不通過增加機器節點的方式提高集群的相應速度和數據承載量。增加機器意味着按照hash取模的方式,在增加機器節點的這一時刻,大量的緩存命不中,緩存數據需要重新建立,甚至是進行整體的緩存數據遷移,瞬間會給DB帶來極高的系統負載,設置導致DB服務器宕機。

如果不是緩存數據,而是持久化的數據,那么當擴容的時候,絕大部分數據都要遷移(取模的基數N變化了),這也是不能忍受的。

 

一致性哈希平衡負載

引入一致性哈希,解決以上增減機器導致負載瞬間整體增大問題

通過在整數范圍內負責各區域的方式,節點負責區域的負載不會隨着增減節點發生大規模的遷移

但是最簡單的一致性哈希,在增減物理機的時候,似乎要增加一倍節點或減去一半節點才能保證各個節點的負載均衡

 

虛擬節點對一致性哈希的改進

對於一致性哈希的負載分布不平均問題,所以提出:虛擬節點對一致性哈希的改進

4個物理節點可以變成很多個虛擬節點,每個虛擬節點支持連續的哈希環上的一段。而這時如果加入一個物理節點,就會相應加入很多虛擬節點,這些新的虛擬節點是相對均勻地插入到整個哈希環上,這樣,就可以很好的分擔現有物理節點的壓力了;如果減少一個物理節點,對應的很多虛擬節點就會失效,這樣,就會有很多剩余的虛擬節點來承擔之前虛擬節點的工作,但是對於物理節點來說,增加的負載相對是均衡的。

所以可以通過一個物理節點對應非常多的虛擬節點,並且同一個物理節點的虛擬節點盡量均勻分布的方式來解決增加或減少節點時負載不均衡的問題。

至於一個物理節點對應多少的虛擬節點才能達到比較好的均衡效果,有一個圖

 

x軸表示的是需要為每台物理服務器擴展的虛擬節點倍數(scale),y軸是實際物理服務器數,可以看出,當物理服務器的數量很小時,需要更大的虛擬節點,反之則需要更少的節點,從圖上可以看出,在物理服務器有10台時,差不多需要為每台服務器增加100~200個虛擬節點才能達到真正的負載均衡。

 

映射表與規則自定義計算方式

映射表示根據分庫分表字段的值的查表法來確定數據源的方法,一般用於對熱點數據的特殊處理,或者在一些場景下對不完全符合規律的規則進行補充。

可以通過自定義函數實現來計算最終的分庫,舉例來說,假設根據id取模分成了4個庫,但是對於一些熱點id,我們希望將其獨立到另外的庫,那么通過類似下面的表達式可以完成:

if (id in  hotset) {
    return nodes;
}
return hash(id);

 

 

參考:

http://www.iteye.com/topic/611976

http://www.iteye.com/topic/684087

《大型網站系統與Java中間件實踐》

http://blog.csdn.net/sparkliang/article/details/5279393

E-mail: huahuiyang@gmail.com https://cn.linkedin.com/pub/huahui-yang/91/13a/105


免責聲明!

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



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