在大規模的緩存應用中,應運而生了分佈式緩存系統。key-value如何均勻的分散到集羣中?最常規的方式莫過於hash取模的方式。好比集羣中可用機器適量爲N,那麼key值爲K的的數據請求很簡單的應該路由到hash(K) mod N對應的機器。可是在一些高速發展的web系統中,這樣的解決方案仍有些缺陷。隨着系統訪問壓力的增加,緩存系統不得不經過增長機器節點的方式提升集羣的相應速度和數據承載量。增長機器意味着按照hash取模的方式,在增長機器節點的這一時刻,大量的緩存命不中,緩存數據須要從新創建,甚至是進行總體的緩存數據遷移,瞬間會給DB帶來極高的系統負載,設置致使DB服務器宕機。node
若是不是緩存數據,而是持久化的數據,那麼當擴容的時候,絕大部分數據都要遷移(取模的基數N變化了),這也是不能忍受的。web
一致性哈希平衡負載算法
引入一致性哈希,解決以上增減機器致使負載瞬間總體增大問題緩存
經過在整數範圍內負責各區域的方式,節點負責區域的負載不會隨着增減節點發生大規模的遷移服務器
可是最簡單的一致性哈希,在增減物理機的時候,彷佛要增長一倍節點或減去一半節點才能保證各個節點的負載均衡負載均衡
虛擬節點對一致性哈希的改進分佈式
對於一致性哈希的負載分佈不平均問題,因此提出:虛擬節點對一致性哈希的改進ide
4個物理節點能夠變成不少個虛擬節點,每一個虛擬節點支持連續的哈希環上的一段。而這時若是加入一個物理節點,就會相應加入不少虛擬節點,這些新的虛擬節點是相對均勻地插入到整個哈希環上,這樣,就能夠很好的分擔現有物理節點的壓力了;若是減小一個物理節點,對應的不少虛擬節點就會失效,這樣,就會有不少剩餘的虛擬節點來承擔以前虛擬節點的工做,可是對於物理節點來講,增長的負載相對是均衡的。函數
因此能夠經過一個物理節點對應很是多的虛擬節點,而且同一個物理節點的虛擬節點儘可能均勻分佈的方式來解決增長或減小節點時負載不均衡的問題。blog
至於一個物理節點對應多少的虛擬節點才能達到比較好的均衡效果,有一個圖
x軸表示的是須要爲每臺物理服務器擴展的虛擬節點倍數(scale),y軸是實際物理服務器數,能夠看出,當物理服務器的數量很小時,須要更大的虛擬節點,反之則須要更少的節點,從圖上能夠看出,在物理服務器有10臺時,差很少須要爲每臺服務器增長100~200個虛擬節點才能達到真正的負載均衡。
映射表與規則自定義計算方式
映射表示根據分庫分表字段的值的查表法來肯定數據源的方法,通常用於對熱點數據的特殊處理,或者在一些場景下對不徹底符合規律的規則進行補充。
能夠經過自定義函數實現來計算最終的分庫,舉例來講,假設根據id取模分紅了4個庫,可是對於一些熱點id,咱們但願將其獨立到另外的庫,那麼經過相似下面的表達式能夠完成:
if (id in hotset) {return nodes;}return hash(id);