Illustrating Six Common Load Balancing Algorithms in Detail – Easy to Understand!

Time: Column:Backend & Servers views:245

Learn about six widely used load balancing algorithms including Round Robin, Weighted Round Robin, Random, Weighted Random, Source IP Hash, and Least Connections. Each algorithm is explained with illustrations, advantages, and implementation examples.

Load balancing refers to distributing client requests across multiple servers to enhance system performance, availability, and scalability. Among the various load-balancing algorithms, the most common include Round Robin, Weighted Round Robin, Random, Weighted Random, Source IP Hash, and Least Connections. Below is a detailed explanation of each algorithm.


Round Robin Algorithm

The Round Robin algorithm is one of the simplest and most commonly used load-balancing techniques. Its implementation is straightforward: requests are forwarded to backend servers sequentially in a predefined order. Typically, this approach assumes that service instances are stateless.

Illustration of Six Common Load Balancing Algorithms: Easy to Understand!

Process Overview:

  1. The first request is sent to Server A.

  2. The second request is sent to the next server, Server B.

  3. The third request is sent to the next server, Server C.

  4. The fourth request starts again at Server A, continuing in a cyclic order.

Advantages:

  • Simple and reliable to implement.

Disadvantages:

  • Does not account for actual server load, potentially leading to uneven workload distribution.

Example Code:

public class RoundRobinDemo {
    private static AtomicInteger index = new AtomicInteger(-1);
    private static List<String> serverList = new ArrayList<>();

    public static String roundRobin() {
        int serverCount = serverList.size();
        int currentServerIndex = index.incrementAndGet() % serverCount;
        return serverList.get(currentServerIndex);
    }

    public static void main(String[] args) {
        serverList.add("Server A");
        serverList.add("Server B");
        serverList.add("Server C");
        System.out.println(roundRobin());
        System.out.println(roundRobin());
        System.out.println(roundRobin());
        System.out.println(roundRobin());
    }
}

Output:

Server A
Server B
Server C
Server A

Weighted Round Robin Algorithm

Weighted Round Robin enhances the Round Robin method by allocating requests based on server capacity or load. Servers with higher capacities or lighter loads are assigned more requests.

Illustration of Six Common Load Balancing Algorithms: Easy to Understand!

Process Overview:

Servers A, B, and C have weights of 4, 3, and 1, respectively. Requests are routed as follows:

  • The first three requests are routed to Server A.

  • The fourth request is routed to Server B.

Advantages:

  • Better suited for handling servers with varying performance.

Disadvantages:

  • Still does not dynamically adjust based on real-time server load.

Example Code:

public class WeightRoundRobinDemo {
    private static AtomicInteger atomicInteger = new AtomicInteger(0);
    private static Map<String, Integer> serverMap = new TreeMap<>();
    private static int totalWeight = 0;

    public static void main(String[] args) {
        serverMap.put("Server A", 4);
        serverMap.put("Server B", 3);
        serverMap.put("Server C", 1);

        for (Map.Entry<String, Integer> entry : serverMap.entrySet()) {
            totalWeight += entry.getValue();
        }

        System.out.println(weightRoundRobin());
        System.out.println(weightRoundRobin());
        System.out.println(weightRoundRobin());
        System.out.println(weightRoundRobin());
    }

    public static String weightRoundRobin() {
        int serverCount = serverMap.size();
        if (serverCount == 0) {
            return null;
        }

        synchronized (serverMap) {
            int currentServerIndex = atomicInteger.incrementAndGet() % totalWeight;

            for (Map.Entry<String, Integer> entry : serverMap.entrySet()) {
                currentServerIndex -= entry.getValue();
                if (currentServerIndex < 0) {
                    return entry.getKey();
                }
            }
        }
        return null;
    }
} }
}

Output:

Server A
Server A
Server A
Server B

Random Algorithm

The Random algorithm distributes requests to servers randomly. While easy to implement, its lack of control may result in uneven server loads. It is often used for testing or temporary scenarios.

Illustration of Six Common Load Balancing Algorithms: Easy to Understand!

Example Code:

private static List<String> serverList = new ArrayList<>();

public static String random() {
    int serverCount = serverList.size();
    if (serverCount == 0) {
        return null;
    }
    int randomIndex = new Random().nextInt(serverCount);
    return serverList.get(randomIndex);
}

Weighted Random Algorithm

Weighted Random assigns requests to servers based on their capacity or load weight, ensuring servers with higher capacity handle more requests.

Illustration of Six Common Load Balancing Algorithms: Easy to Understand!

Example Code:

private static Map<String, Integer> serverMap = new ConcurrentHashMap<>();

public static String weightRandom() {
    int serverCount = serverMap.size();
    if (serverCount == 0) {
        return null;
    }

    synchronized (serverMap) {
        int totalWeight = serverMap.values().stream().mapToInt(Integer::intValue).sum();
        int randomWeight = new Random().nextInt(totalWeight);

        for (Map.Entry<String, Integer> entry : serverMap.entrySet()) {
            randomWeight -= entry.getValue();
            if (randomWeight < 0) {
                return entry.getKey();
            }
        }
    }
    return null;
}

Source IP Hash Algorithm

This algorithm uses the client’s IP address as a hash key to determine the target server. It ensures requests from the same client are routed to the same server.

Illustration of Six Common Load Balancing Algorithms: Easy to Understand!

Example Code:

private static List<String> serverList = new ArrayList<>();

public static String hash(String clientIP) {
    int serverCount = serverList.size();
    if (serverCount == 0) {
        return null;
    }
    int hashCode = clientIP.hashCode();
    int serverIndex = hashCode % serverCount;
    return serverList.get(serverIndex);
}

Least Connections Algorithm

This algorithm dynamically routes requests to the server with the fewest active connections.

Illustration of Six Common Load Balancing Algorithms: Easy to Understand!

Example Code:

private static List<String> serverList = new ArrayList<>();
private static Map<String, Integer> connectionsMap = new ConcurrentHashMap<>();

public static String leastConnections() {
    int serverCount = serverList.size();
    if (serverCount == 0) {
        return null;
    }

    String selectedServerAddress = serverList.get(0);
    int minConnections = connectionsMap.getOrDefault(selectedServerAddress, 0);

    for (int i = 1; i < serverCount; i++) {
        String serverAddress = serverList.get(i);
        int connections = connectionsMap.getOrDefault(serverAddress, 0);
        if (connections < minConnections) {
            selectedServerAddress = serverAddress;
            minConnections = connections;
        }
    }
    return selectedServerAddress;
}

Note:
Dynamic updates to server states (e.g., adding or removing servers) may require recalculations, potentially impacting performance.