分佈式理論基礎認知:一致性哈希算法(已完成遷移)

一:一致性hash算法
    一致性hash場景描述:
        假如有三臺緩存服務器,此時一個數據要緩存到其中一臺,並且要一次查詢快速定位。一種簡單實用的方法就是
        對此時數據標識(key)進行hash取值,然後根據hash值與服務器數量取餘獲得餘數,此數代表了那一臺服務器,
        此時數據就緩存在這臺服務器上。但是會有個問題,當緩存服務器數量增加或者減少時,原先緩存的數據因爲
        服務器數量的增加或者減少,導致餘數變化,此時獲取緩存肯定是失效的,而且是全局緩存失效,這時導致緩存
        失去意義,這種情況下,出現了一致性hash

    概念:
        上述普通算法是根據服務器數量進行取模運算,而一致性hash就是對 2^32 取模
        把 2^32 想象成一個圓,也就是一個圓上分佈了 2^32 個點,又被稱爲 hash環
        上述hash值對 2^32 取模後(假設爲A),會落在 0-2^32-1 上的某一個點,而此時用 服務器ip % 2^32 取模之後的數,
        代表此時服務器所在的點(假設爲B),假設 A等於B 或者 A在B的逆時針方向,且靠的最近(hash環是按照順時針方向
        定義,也就是A會找最近並且在它的順時針方向上的點,即大的點)
        出現服務器數量增加或者減少後,hash值對於 2^32 取模後的值是相對不變的,也就是緩存的點總是不變,變化的只是
        hash環上某一節點上服務器數的增減,但是影響只限於增減那一段上的,其他地方不會影響。這就是一致性hash相對於普通
        hash的優點

    優點:隻影響增減那一段上的數據,其它節點上無感知,正常運行。而普通的取模算法就會導致所有的節點數據異常,一個影響
        部分,一個影響全部


    hash環的偏斜:
        對於服務器ip進行hash取模,很大可能各個節點不是均勻散落在hash環上,這就是hash環的偏斜,由此會導致某一服務器
        上會分佈大量數據,而爲了防止這種現象,使用“虛擬節點”解決此問題

    虛擬節點:
        虛擬節點是真實節點在hash環上的複製品,一個真實節點可以對應許多的虛擬節點,當然虛擬節點越多,分佈就會越均勻,
        數據分佈效果越好。
        分析:比如有一百個虛擬節點,從1-100,hash值+ 1-100 ,然後取模,此時大的數取值會大,小的數取值會小,效果也不好
        此時 hash算法要定義一個儘量差異大的,這樣相近的hash也會分散開,使得多個節點及其虛擬節點相互混雜,這樣
        效果越好,使用虛擬節點就解決了hash環偏斜的問題

二:代碼實現及其使用測試
    代碼實現:Ketama.java
    使用:
    /*
     * 一致性hash實現:將所有的在線服務都存儲到統一 treeMap中,進行負載均衡(路由到其他地址)
     */
    List servers = new ArrayList<>();
    for (String server : servers){
        Logs.info("server router add ketama server({})", server);
        ketama.add(server);
    }
    
    測試:Ketama.java中 main() 方法,詳細介紹如何使用


###資料鏈接
 hash一致性 經典理解:http://www.zsythink.net/archives/1182/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章