Backend Development 34 min read

Load Balancing Algorithms: Round Robin, Random, Weighted, Smooth Weighted, Consistent Hashing, Least Active and Optimal Response

This article explains common load‑balancing strategies—including basic round‑robin, random, weighted and smooth weighted algorithms, as well as consistent hashing, least‑active and optimal‑response methods—provides Java implementations for each, discusses their advantages, disadvantages, and suitable scenarios, and concludes with practical recommendations.

Architect
Architect
Architect
Load Balancing Algorithms: Round Robin, Random, Weighted, Smooth Weighted, Consistent Hashing, Least Active and Optimal Response

Load balancing is a fundamental technique used in high‑availability systems such as micro‑services, distributed databases, and cloud platforms. The article first classifies load‑balancing strategies into static and dynamic categories and then dives into several widely used algorithms.

Basic Load‑Balancing Algorithms

Round‑robin distributes requests sequentially across servers. The Java implementation uses an AtomicInteger to track the request index and selects a server by index % serverCount . Random selection picks a server using java.util.Random . Both are simple, high‑throughput methods but do not consider server capacity.

public class RoundRobin {
    private static AtomicInteger requestIndex = new AtomicInteger(0);
    public static String getServer() {
        int index = requestIndex.get() % Servers.SERVERS.size();
        requestIndex.incrementAndGet();
        return Servers.SERVERS.get(index);
    }
}
public class Random {
    private static java.util.Random random = new java.util.Random();
    public static String getServer() {
        return Servers.SERVERS.get(random.nextInt(Servers.SERVERS.size()));
    }
}

Weighted Algorithms

Weighted round‑robin and weighted random assign a weight to each server, allowing higher‑capacity nodes to receive more traffic. The implementations store a Map<String, Integer> of server weights and calculate a cumulative weight to select a server.

public class RandomWeight {
    public static String getServer() {
        int totalWeight = 0;
        for (Integer w : Servers.WEIGHT_SERVERS.values()) totalWeight += w;
        int index = random.nextInt(totalWeight);
        for (Map.Entry
e : Servers.WEIGHT_SERVERS.entrySet()) {
            if (index < e.getValue()) return e.getKey();
            index -= e.getValue();
        }
        return null;
    }
}

Smooth Weighted Round‑Robin

This algorithm solves the uneven distribution problem of simple weighted round‑robin by maintaining a dynamic weight for each server. On each request the algorithm adds the static weight to the current weight, selects the server with the highest current weight, then subtracts the total weight from that server’s current weight.

public class SmoothWeightedRoundRobin {
    private static Map
weightMap = new HashMap<>();
    private static int totalWeight = 0;
    static { sumWeightTotal(); }
    public static String getServer() {
        if (weightMap.isEmpty()) {
            Servers.WEIGHT_SERVERS.forEach((s,w) -> weightMap.put(s, new Weight(s,w,0)));
        }
        weightMap.values().forEach(v -> v.currentWeight += v.weight);
        Weight max = Collections.max(weightMap.values(), Comparator.comparingInt(v -> v.currentWeight));
        max.currentWeight -= totalWeight;
        return max.server;
    }
}

Consistent Hashing

Consistent hashing maps both servers and request keys onto a 2^32‑size hash ring, ensuring that a request is always routed to the first server clockwise from its hash value. Virtual nodes are added to improve distribution and reduce the impact of node addition or removal.

public class ConsistentHash {
    private static TreeMap
virtualNodes = new TreeMap<>();
    private static final int VIRTUAL_NODES = 160;
    static {
        for (String ip : Servers.SERVERS) {
            virtualNodes.put(hash(ip), ip);
            for (int i=0;i
tail = virtualNodes.tailMap(hash);
        int nodeKey = tail.isEmpty() ? virtualNodes.firstKey() : tail.firstKey();
        return virtualNodes.get(nodeKey);
    }
}

Least‑Active Algorithm

The least‑active strategy selects the server with the smallest number of ongoing requests, updating the count atomically and periodically decaying the activity metric.

public class LeastActive {
    public static String getServer() {
        int least = Integer.MAX_VALUE;
        Server target = null;
        for (Server s : Servers.SERVERS) {
            int act = s.getActive().get();
            if (act < least) { least = act; target = s; }
        }
        return target.getIP();
    }
}

Optimal‑Response Algorithm

This dynamic method pings all servers concurrently (using CompletableFuture ) and chooses the one that replies first, ensuring the fastest response time for each request.

public class ResponseTime {
    private static ExecutorService pool = Executors.newFixedThreadPool(Servers.SERVERS.size());
    public static String getServer() throws InterruptedException {
        CompletableFuture
[] futures = Servers.SERVERS.stream()
            .map(s -> CompletableFuture.supplyAsync(s::ping, pool))
            .toArray(CompletableFuture[]::new);
        CompletableFuture
any = CompletableFuture.anyOf(futures);
        return (String) any.get();
    }
}

Conclusion

The article compares static and dynamic load‑balancing algorithms, noting that while sophisticated methods (smooth weighted, consistent hashing, least‑active, optimal‑response) provide better distribution and fault tolerance, they also introduce higher computational overhead. In ultra‑high‑throughput scenarios with homogeneous servers, simple round‑robin may still be the most efficient choice.

Distributed SystemsJavaLoad BalancingAlgorithmsconsistent hashingleast activeoptimal response
Architect
Written by

Architect

Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.