常見的一些負載均衡算法總結

負載均衡算法在很多地方都有使用,無論是在服務治理中或者是在分布式緩存中都大量的使用,本文主要介紹幾種常見的負載均衡的算法.

1.輪詢法.

    輪詢法,很好理解,將請求按照順序輪流的分配到服務器上,他均衡的對待每一臺后端的服務器,
不關心服務器的的連接數和負載情況.以下代碼演示了這種算法.

public class BalanceServer {

    public static List<String> servers = Arrays.asList("192.168.0.1", "192.168.0.2", "192.168.0.3", "192.168.0.4",
            "192.168.0.5");
    
    public static int pos = 0;

    public static String getServer() {

        String server = null;

        if (pos >= servers.size()) {
            pos = 0;
        }

        server = servers.get(pos);
        pos++;

        return server;
    }

    public static void main(String[] args) {
        for(int i=0;i<10;i++){
            System.out.println(BalanceServer.getServer());
        }
    }
    
}

輪詢的策略目的在于請求的絕對均衡,但是在實際的情況下,可能服務器并不是完全一樣.
導致有些性能高的服務器不能完全發揮出來.

2.隨機法

通過系統的隨機函數,根據后端服務器列表的大小來隨機獲取其中的一臺來訪問,隨著調用量的增大,
實際效果越來越近似于平均分配到沒一臺服務器.和輪詢的效果類似.

public class BalanceServer {

    public static List<String> servers = Arrays.asList("192.168.0.1", "192.168.0.2", "192.168.0.3", "192.168.0.4",
            "192.168.0.5");
    
    public static int pos = 0;

    public static String getServer() {
        
        String server = null;
        
        Random random = new Random();
        int randomPos = random.nextInt(servers.size());
        
        server = servers.get(randomPos);
        
        return server;
    }

}

和輪詢算法比較,在并發的場景下,輪詢需要加鎖,隨機法想比而言性能好點.

3.源地址hash法.

源地址hash法的思想是獲取客戶端訪問的ip地址,通過hash函數計算出一個hash值,用該hash值對服
務器列表的大小進行取模運算,得到的值就是要訪問的服務器的序號.

public class BalanceServer {

    public static List<String> servers = Arrays.asList("192.168.0.1", "192.168.0.2", "192.168.0.3", "192.168.0.4",
            "192.168.0.5");
    
    public static int pos = 0;

    public static String getServer(String ip) {
        
        String server = null;
        
        int hashCode = ip.hashCode();
        pos = hashCode % servers.size();
        
        server = servers.get(pos);
        
        return server;
    }
}

hash法的好處是,在服務器列表不變的情況下,每次客戶端訪問的服務器都是同一個服務器.利用這個
特性可以有狀態的session會話.無需額外的操作就可以實現粘性會話.

  1. 加權輪詢法.
  剛剛有說道過,不同的服務器性能不同,所以不能一概而論,需要給性能低的服務器給比較低的
權重,性能高的給跟高的權重.

public class BalanceServer {

    public static Map<String, Integer> serverMap = new HashMap<String, Integer>();
    public static int pos = 0;
    static {
        serverMap.put("192.168.0.1", 1);
        serverMap.put("192.168.0.2", 1);
        serverMap.put("192.168.0.3", 4);
        serverMap.put("192.168.0.4", 3);
        serverMap.put("192.168.0.5", 3);
        serverMap.put("192.168.0.6", 2);
    }

    public static String getServer() {
        Set<String> keySet = serverMap.keySet();
        Iterator<String> it = keySet.iterator();

        List<String> servers = new ArrayList<String>();
        while (it.hasNext()) {
            String server = it.next();
            Integer weight = serverMap.get(server);
            for (int i = 0; i < weight; i++) {
                servers.add(server);
            }
        }

        String server = null;

        if (pos >= servers.size()) {
            pos = 0;
        }

        server = servers.get(pos);
        pos++;

        return server;
    }

    public static void main(String[] args) {
        for(int i=0;i<14;i++){
            System.out.println(BalanceServer.getServer());
        }
    }
}

5.加權隨機法,
加權隨機法算法和加權輪詢法類似.就不多說了.

  1. 有關hash算法的一些補充說明
在上面的hash算法中,存在以下的幾個問題
  1.當一臺服務器宕機了或者新添加一臺機器之后,這個時候hashCode % servers.size()
 需要重新計算hash值, 如果在緩存的環境中,所有的請求都會涌向數據庫服務
器,給數據庫服務器帶來巨大的壓力,可能導致整個系統不可用,形成雪崩效應.

  2 .當新增了一臺性能強的機器后,利用上述的hash算法無法讓,新增的性能強的服務器多承擔壓力.

基于上面的幾個問題,提出了hash算法的改進,consistent hash算法,consistent hashing
也是一種 hash 算法,簡單的說,在移除 / 添加操作,它能夠盡可能小的改變已存在 key 映射關系.

consistent hash算法的原理是它將hash函數的值域組織成一個
環形,整個空間按照順時針的方式進行組織,將對應的服務器節點進行hash,將他們映射到
hash環上,假設有四臺機器node1-4,hash之后如圖所示:
consistent hashing.png
接下來使用相同的hash函數,計算出對應的key值和hash值,按照順時針的方式,分布在node1和node2
的key,訪問時被定位在node2,分布在node2和node4的key被定位在node4上,以此類推.假設現
在新增一個node5,假設hash之后在node2和node4之間,如圖所示:
新增node.png
那么受影響的節點只有node2和node5,他們將會從新hash,而其他的key的映射將不會變化.
當然,上面描繪了一種很理想的情況,各個節點在環上分布的十分均勻.正常情況下,當節點數量少的
時候,節點分布并不均勻,這時需要引入虛擬節點機制.

總結:本篇只是概述了幾種常見的均衡負載算法,有關 consistent hash算法,可以參考http://blog.csdn.net/sparkliang/article/details/5279393

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 【摘要】 面對大量用戶訪問、高并發請求,海量數據,可以使用高性能的服務器、大型數據庫,存儲設備,高性能Web服務器...
    靜修佛緣閱讀 4,610評論 0 24
  • 摘要:面對大量用戶訪問、高并發請求,海量數據,可以使用高性能的服務器、大型數據庫,存儲設備,高性能Web服務器,采...
    layjoy閱讀 13,864評論 3 93
  • 前言 前不久公司有個需求是任務需要按照權重分配來選擇,當時就想到負載均衡算法里的加權隨機法,因此對常見的負載均衡算...
    FlySheep_ly閱讀 1,911評論 2 2
  • 分布式架構實踐——負載均衡 也許當我老了,也一樣寫代碼;不為別的,只為了愛好。 1 什么是負載均衡(Load ba...
    Bobby0322閱讀 7,481評論 1 27
  • 上個月上海之行(上音古箏學術論壇)于我個人產生了一些思想上的沖擊。 首先,自己很羨慕上音所擁有的強大的學術資源和氛...
    一只愛生活的羊閱讀 261評論 0 0