Load balancing algorithms commonly used in Distributed Systems

For the students who are doing the development, the load balancing algorithm is no stranger. Today, let's check the load balancing algorithm in the distributed system and its advantages and disadvantages;

1. Round Robin

Idea: the requests are distributed to the back-end servers in turn. It treats each back-end server in a balanced way, and does not care about the actual number of connections and the load of the current system;
Code implementation:

private List<String> list = new CopyOnWriteArrayList();
private volatile Integer pos = 0;

{
    list.add("127.0.0.1");
    list.add("127.0.0.2");
    list.add("127.0.0.3");
}

public String getServer() {
    if (null == list || list.size() <= 0) {
        return null;
    }
    String server = null;
    synchronized (pos) {
        if (pos >= list.size()) {
            pos = 0;
        }
        server = list.get(pos++);
    }
    return server;
}

Summary:

This algorithm is simple, forwarding in turn, and the number of requests per server is average;
Disadvantages: when the performance of servers in a cluster is different, resources will be wasted if they cannot be treated differently;

2. Random method

Idea: through the system random function, according to the size value of the back-end server list, one of them is randomly selected for access; with the increase of the amount of call, the effect is close to the polling algorithm;
Code implementation:

private List<String> list = new CopyOnWriteArrayList();
{
    list.add("127.0.0.1");
    list.add("127.0.0.2");
    list.add("127.0.0.3");
    list.add("127.0.0.4");
}

public String getServerRandom() {
    if (null == list || list.size() <= 0) {
        return null;
    }
    Random random = new Random();
    String server = list.get(random.nextInt(list.size()));
    return server;
}

Summary:

Although the algorithm is simple, it can guarantee the balance in the case of large requests

3. Source address Hash

Idea: the idea of source address hash is to obtain the ip address accessed by the client, get a value through hash function calculation, and use the value to carry out modular operation from the server list; when the server list is unchanged, the same ip is always requested to the same server;
Code implementation:

private List<String> list = new CopyOnWriteArrayList();
{
    list.add("127.0.0.1");
    list.add("127.0.0.2");
    list.add("127.0.0.3");
    list.add("127.0.0.4");
}

public String getServerHash(String hostIp) {
    if (null == list || list.size() <= 0 || null == hostIp) {
        return null;
    }
    int code = hostIp.hashCode();
    int serverPos = list.size() % code;
    return list.get(serverPos);
}

4. Weight Round Robin

Idea: compared with polling algorithm, it adds weight, and the service with super high weight receives more requests;
Code implementation:

private ConcurrentMap<String, Integer> hosts = new ConcurrentHashMap<>();
private volatile Integer pos = 0;

{
    hosts.put("127.0.0.1", 1);
    hosts.put("127.0.0.2", 2);
    hosts.put("127.0.0.3", 2);
    hosts.put("127.0.0.4", 1);
}

public String getServerRoundRobin() {
    List<String> list = new ArrayList<>();

    for (Map.Entry<String, Integer> entry : hosts.entrySet()) {
        Integer value = entry.getValue();
        for (int i = 0; i < value; i++) {
            list.add(entry.getKey());
        }
    }

    String server = null;
    synchronized (pos) {
        if (pos >= list.size()) {
            pos = 0;
        }
        server = list.get(pos++);
    }
    return server;
}

5. Weight Random

Thought: on the basis of random, add weight;
Code implementation:

private ConcurrentMap<String, Integer> hosts = new ConcurrentHashMap<>();
private volatile Integer pos = 0;

{
    hosts.put("127.0.0.1", 1);
    hosts.put("127.0.0.2", 2);
    hosts.put("127.0.0.3", 2);
    hosts.put("127.0.0.4", 1);
}
public String getServerRandomWeight() {
    List<String> list = new ArrayList<>();

    for (Map.Entry<String, Integer> entry : hosts.entrySet()) {
        Integer value = entry.getValue();
        for (int i = 0; i < value; i++) {
            list.add(entry.getKey());
        }
    }

    Random random = new Random();
    String server = list.get(random.nextInt(list.size()));
    return server;
}

The above two ways to realize weighting are to add several times to the list, if the number of servers is large, the list will be too large; another way to realize weighting is to divide each service and weight into a segment, the larger the weight, the longer the segment

Code implementation:

private Map<String, Integer> hosts = new ConcurrentHashMap<>();
private volatile Integer pos = 0;

{
    hosts.put("127.0.0.1", 1);
    hosts.put("127.0.0.2", 2);
    hosts.put("127.0.0.3", 2);
    hosts.put("127.0.0.4", 1);
}
public String getServerRandomWeight2() {
    // Accumulate all weights
    int sum = 0;
    for (Map.Entry<String, Integer> entry : hosts.entrySet()) {
        sum += entry.getValue();
    }
    Random random = new Random();
    int index = random.nextInt(sum);
    for (Map.Entry<String, Integer> entry : hosts.entrySet()) {
        Integer value = entry.getValue();
        if(value >= index){
            return entry.getKey();
        }
        index -= entry.getValue();
    }
    return null;
}

6. Least Connections

Idea: the minimum number of connections method is to balance the load according to the current connection situation of the server. It will choose a machine with the least number of connections to provide services;
Code implementation:

// key: machine IP value: current access
private Map<String, Integer> hosts = new ConcurrentHashMap<>();
private volatile Integer pos = 0;

{
    hosts.put("127.0.0.1", 6);
    hosts.put("127.0.0.2", 2);
    hosts.put("127.0.0.3", 3);
    hosts.put("127.0.0.4", 8);
}

public String getServerLeastConnection() {
    // Find the minimum connection
    int min = 0;
    String key = null;
    for (Map.Entry<String, Integer> entry : hosts.entrySet()) {
        if (entry.getValue() < min) {
            min = entry.getValue();
            key = entry.getKey();
        }
    }
    hosts.put(key, min + 1);

    return key;
}

Note: the code implementation in this paper is not suitable for the real scene, just for the simple and easy understanding of algorithm ideas;

Tags: Java

Posted on Thu, 07 May 2020 22:18:58 -0400 by Wade