Summary of Load Balancing Algorithms
Stochastic algorithm
Firstly, the server is put into an array or a list, and a subscript within the valid range of the array is obtained through the random algorithm of JDK. According to the random subscript, the corresponding server is accessed. From the theory of probability and statistics, we can know that with the increase of the number of client calls to the server, the actual effect is more and more close to the average allocation of requests to each server in the server list.
Code:
public String random(){ String[] servers = {"server1", "server2", "server3"}; // Obtaining a randomizer with the current time of the system as a seed Random generator = new Random(System.currentTimeMillis()); // Pass in the server list size as the upper bound to the random generator int index = generator.nextInt(servers.length); return servers[index]; }
Weighted Random Algorithms
If the processing performance of the server is high or low, then weighted random algorithm is needed. The weighted stochastic algorithm is also very simple. There are two main forms:
A very simple form is to increase the number of servers in the list according to the weight of the server. For example, the weight of server A is 7, and the weight of server B is 3. Then seven A servers and three B servers are added to the list of servers. At this time, the random algorithm will have the effect of weighting.
Code:
public String weightRandomA(){ // Server List String[] servers = {"serverA", "serverB"}; // weight int[] weights = {7, 3}; List<String> weightServers = new ArrayList<>(); // Repeat adding the corresponding server to the new list of weighted servers according to the weight size for (int i = 0; i < servers.length; i++) { for (int j = 0; j < weights[i]; j++) { weightServers.add(servers[i]); } } // Obtaining a randomizer with the current time of the system as a seed Random generator = new Random(System.currentTimeMillis()); // Pass in the server list size as the upper bound to the random generator int index = generator.nextInt(weightServers.size()); return weightServers.get(index); }
However, there is also a problem here, that is, if the weight value is very large, the list of weight servers will be too large. The other way is to add the weight of ownership and then extract the server randomly according to the upper bound of random number. For example, the weight of server A is 2, that of server B is 3, and that of server C is 5. The total weight value is 10. Take random numbers in 10. If the random number is between 0 and 2, choose A server, if the random number is between 3 and 5, choose B server, if the random number is between 5 and 10, choose C server.
Code:
public String weightRandomB(){ // Server List String[] servers = {"serverA", "serverB","serverC"}; // weight int[] weights = {2, 3, 5}; // Total weight int totalWeight = 0; // Calculate the total weight for (int weight : weights) { totalWeight += weight; } // Obtaining a randomizer with the current time of the system as a seed Random generator = new Random(System.currentTimeMillis()); // The total weight is fed into the random generator as the upper bound to obtain a temporary random weight value. int randomWeight = generator.nextInt(totalWeight); // Server list subscript int index = 0; // If the decreasing random weight value is less than 0, it will fall into the corresponding interval. Find the server according to the subscript. for (int i = 0; i < weights.length; i++) { randomWeight -= weights[i]; if (randomWeight <= 0) { index = i; break; } } return servers[index]; }
polling algorithm
Random algorithm is simple and feasible, but it is not balanced enough. In extreme cases, one server always receives requests and the other server never receives requests. So polling algorithm is needed at this time. You can call the servers in the server list in turn. For example, there are three ABC servers in the list of servers, one self-increasing number, each self-increasing the remainder of 3, 0 for server A, 1 for server B, 2 for server C.
Code:
public String roundRobin(){ String[] servers = {"serverA", "serverB", "serverC"}; // Divide the number of server lists by self-incremental sequence values int currentIndex = serialNumber % servers.length; // When calculating the subscript of the server list, the self-increasing sequence + 1 //(Class variables are currently used and Atomic atomic variables are actually developed) serialNumber++; return servers[currentIndex]; }
General weighted polling algorithm
If the performance of different servers is taken into account, a weighted polling algorithm is needed.
For example, the weight of server A is 5, that of server B is 3, and that of server C is 2. Add it to the list of servers in turn, where the list of servers is [A, A, A, A, B, B, C, C]. The weighted polling algorithm can be implemented by polling the servers in the list in turn.
Code:
public String weightRoundRobinA() { // Server List String[] servers = {"serverA", "serverB","serverC"}; // weight int[] weights = {5, 3, 2}; List<String> weightServers = new ArrayList<>(); // Repeat adding the corresponding server to the new list of weighted servers according to the weight size for (int i = 0; i < servers.length; i++) { for (int j = 0; j < weights[i]; j++) { weightServers.add(servers[i]); } } // Divide the number of weighted server lists by self-incremental sequence values int currentIndex = serialNumber % weightServers.size(); // When calculating the subscript of the server list, the self-increasing sequence + 1 //(Class variables are currently used and Atomic atomic variables are actually developed) serialNumber++; return weightServers.get(currentIndex); }
When the weight value is very large, the list will be very long. At this time, the maximum common denominator of ownership weight can be taken to accumulate, and the corresponding server can be taken when it falls in the corresponding interval. For example, the weight of server A is 10, the weight of server B is 3, and the weight of server C is 2. Take the number of conventions 2, and use the algorithm just now. Each time, the number of conventions increases by 2 in self-increasing sequence.
Smooth weighted polling algorithm
The above weighted polling algorithm will result in continuous calls to the same server. At this time, the request distribution is very unbalanced. It is always necessary to call the same server continuously according to the weight value before calling the next server.
At this time, a smooth weighting algorithm is needed.
Assume server A configuration weight is 7, server B configuration weight is 2, and server configuration weight is 1.
The total weight is 10. The scheduling of smooth weighted polling is as follows. The effective weight of each server is the current weight. Unlike the configuration weight, the effective weight is calculated based on the previous round. In each round, the server with the largest weight is selected for requests. For the selected node, the current effective weight is subtracted from the total weight. Valid weights of all servers plus their own configuration weights before the next round starts.
- Server A weight: 7
- Server B weight: 2
- Server C Weight: 1
- Total weight: 10
- Each server in each round adds its own configuration weight
Rotation | Server A | Server B | Server C | Server currently selected (current maximum weight) |
---|---|---|---|---|
first round | 7 | 2 | 1 | A (Current Weight-Total Weight=-3) |
The second round | 4 | 2 | 2 | A (Current Weight-Total Weight=-6) |
Third round | 1 | 6 | 3 | B (Current Weight-Total Weight=-4) |
The fourth round | 8 | -2 | 4 | A (Current Weight-Total Weight=-2) |
The fifth round | 5 | 0 | 5 | A (Current Weight-Total Weight=-5) |
The sixth round | 2 | 2 | 6 | C (Current Weight-Total Weight=-4) |
The seventh round | 9 | 4 | -3 | A (Current Weight-Total Weight=-1) |
The eighth round | 6 | 6 | -2 | A (Current Weight-Total Weight=-4) |
The ninth round | 3 | 8 | -1 | B (Current Weight-Total Weight=-2) |
The tenth round | 10 | 0 | 1 | A (Current Weight - Total Weight = 0) |
In this way, there will be no repeated calls to the same server.
Code:
public String smoothWeightRouncRobin() { // Server List String[] servers = {"serverA", "serverB","serverC"}; // weight int[] weights = {7, 2, 1}; // Total weight int totalWeight = 0; // Calculate the total weight for (int weight : weights) { totalWeight += weight; } int maxWeightIndex = 0; // CurrtWeights is a class variable that holds the current weights of three servers // Finding the Subscript with the Maximum Current Weight Value for (int i = 0; i < currentWeights.length; i++) { if (currentWeights[i] > currentWeights[maxWeightIndex]) { maxWeightIndex = i; } } // The current maximum weight subtracts the total weight currentWeights[maxWeightIndex] = currentWeights[maxWeightIndex] - totalWeight; // Add its configuration weight to each server in turn for (int i = 0; i < currentWeights.length; i++) { currentWeights[i] = currentWeights[i] + weights[i]; } return servers[maxWeightIndex]; }
Hash algorithm
The request can be hashed with the ip address or the url of the request and distributed to the corresponding server.
Minimum Connection Number Algorithms
The minimum number of connections method is load balancing according to the current connection situation of the server. When the request arrives, the server with the least number of connections will be selected to process the request.