Load balancing algorithm

Posted by hiberphoptik on Mon, 20 Dec 2021 18:39:50 +0100

Summarize the video of up main IT brother from b station

summary

Common load balancing algorithms include random, weighted random, polling, weighted polling, smooth weighted polling and consistent hash

algorithm

  • Server IP
public class ServerIps {
    public static final List<String> LIST = Arrays.asList(
            "A",
            "B",
            "C"
    );
    //Weighted
    public static final Map<String,Integer> WEIGHT_LIST = new LinkedHashMap<String, Integer>();
    static {
        WEIGHT_LIST.put("A",2);
        WEIGHT_LIST.put("B",3);
        WEIGHT_LIST.put("C",5);
    }
}

random

  • Random is to randomly forward requests to a server
//random
public class RandomSelect {
    public static String getServer() {
        Random random = new Random();
        int rand = random.nextInt(ServerIps.LIST.size());
        return ServerIps.LIST.get(rand);
    }

    public static void main(String[] args) {
        System.out.println(getServer());
        System.out.println(getServer());
        System.out.println(getServer());
    }
}

test

polling

  • Polling is to forward requests to each server in turn
public class RoundRobin {
    //position
    public static Integer pos = 0;
    public static String getServer() {
        String ip = null;
        synchronized (pos) {
            if(pos >= ServerIps.LIST.size()) {
                pos = 0;
            }
            ip = ServerIps.LIST.get(pos);
            pos++;
        }
        return ip;
    }

    public static void main(String[] args) {
        System.out.println(getServer());
        System.out.println(getServer());
        System.out.println(getServer());
        System.out.println(getServer());
        System.out.println(getServer());
        System.out.println(getServer());
    }
}

test

Weighted random

  • Weighted randomization means that each server has different probability of being randomized

Implementation mode I

  • Use the set to add the server ip to the set according to the weight, then generate a random number (< set size), then obtain the server at the random number index and forward the request to the server
//The larger the weight of ips, the more random the weight of memory
public class WeightRandom {
    public static String getServer() {
        //Generate random numbers as List Subscripts
        List<String> ips = new ArrayList<>();

        for (String ip: ServerIps.WEIGHT_LIST.keySet()) {
            Integer weight = ServerIps.WEIGHT_LIST.get(ip);
            //How much weight is stored in ips? How many examples are stored in ips? A weight is 2, and two are stored in ips
            for (int i = 0; i < weight ; i++) {
                ips.add(ip);
            }
        }
        Random random = new Random();
        int randomPos = random.nextInt(ips.size());
        return ips.get(randomPos);
    }

    public static void main(String[] args) {
        System.out.println(getServer());
        System.out.println(getServer());
        System.out.println(getServer());
        System.out.println(getServer());
        System.out.println(getServer());
        System.out.println(getServer());
    }
}

test

Implementation mode 2


Execution process:

  • Gets the total weight of the server
  • Then get the random number (less than the total weight)
  • Traverse the server in turn. If the random number is greater than the weight of the current server, subtract the weight from the random number. Otherwise, forward the request to the server
//Weighted random
public class WeightRandomV2 {
    public static String getServer() {
        //Total weight
        int totalWeights = ServerIps.WEIGHT_LIST.values().stream().mapToInt(w -> w).sum();

        Random random = new Random();
        int pos = random.nextInt(totalWeights);

        for(String ip: ServerIps.WEIGHT_LIST.keySet()) {
            Integer weight = ServerIps.WEIGHT_LIST.get(ip);
            if(pos < weight) {
                return ip;
            }
            pos = pos - weight;
        }

        return "";
    }

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

test

Weighted polling

  • Similar to weighted random

Implementation mode I

  • Traverse the server ip, use a set, and add each server to the corresponding weight times in the set,
  • Define variable save access count, and return list each time Server for get (count% list. Size())
//Disadvantages: the larger the weight of ips, the larger the weight of memory
public class WeightRoundRobinV0 {

    //Number of visits
    static int count = 0;

    public static String getServer() {
        //Generate random numbers as List Subscripts
        List<String> ips = new ArrayList<>();

        for (String ip: ServerIps.WEIGHT_LIST.keySet()) {
            Integer weight = ServerIps.WEIGHT_LIST.get(ip);
            //How much weight is stored in ips? How many examples are stored in ips? A weight is 2, and two are stored in ips
            for (int i = 0; i < weight ; i++) {
                ips.add(ip);
            }
        }
        String ip = ips.get(count % ips.size());
        ++count;
        return ip;
    }

    public static void main(String[] args) {
        System.out.println(getServer());
        System.out.println(getServer());
        System.out.println(getServer());
        System.out.println(getServer());
        System.out.println(getServer());
        System.out.println(getServer());
        System.out.println(getServer());
        System.out.println(getServer());
        System.out.println(getServer());
        System.out.println(getServer());
    }

}

test

Implementation mode 2

  • Similar to weighted random
//Polling optimization
public class WeightRoundRobin {
    public static String getServer(Integer num) {

        int totalWeights = ServerIps.WEIGHT_LIST.values().stream().mapToInt(w -> w).sum();

        Integer pos = num % totalWeights;

        for(String ip: ServerIps.WEIGHT_LIST.keySet()) {
            Integer weight = ServerIps.WEIGHT_LIST.get(ip);
            if(pos < weight) {
                return ip;
            }
            pos = pos - weight;
        }

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

test

Smooth weighted polling

  • The above weighted polling will continuously access a server many times. We can optimize it and disperse the requests. Don't always access a server
  • Each request returns the result in the operation shown in the figure below
public class WeightRoundRobinV2 {

    public static Map<String,Weight> currWeights = new HashMap<>();

    public static String getServer() {

        int totalWeights = ServerIps.WEIGHT_LIST.values().stream().mapToInt(w -> w).sum();

        //currentWeight defaults to 0, and currentWeight is initialized
        if(currWeights.isEmpty()) {
            ServerIps.WEIGHT_LIST.forEach((ip,weight)->
            {
                currWeights.put(ip,new Weight(ip,weight,0));
            });
        }

        //Traverse dynamic weight, dynamic weight plus current weight
        for(Weight weight: currWeights.values()) {
            weight.setCurrentWeight(weight.getCurrentWeight() + weight.getWeight());
        }

        //Find maximum value
        Weight maxCurrentWeight = null;
        for(Weight weight: currWeights.values()) {
            if(maxCurrentWeight == null || weight.getCurrentWeight() > maxCurrentWeight.getCurrentWeight()) {
                maxCurrentWeight = weight;
            }
        }

        maxCurrentWeight.setCurrentWeight( maxCurrentWeight.getCurrentWeight() - totalWeights);

        return maxCurrentWeight.getIp();
    }

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

test

  • Through the running results, we can know that the requests are successfully distributed to each server according to the weight. (C5,B3,A2)

Consistency hash

Recommend an easy to understand article: https://www.cnblogs.com/lpfuture/p/5796398.html

  • Treemap (using the data structure of red black tree and ordered map) is used to simulate obtaining a node on the hash ring

Topics: Java Operation & Maintenance Load Balance Algorithm