Consistent hashing load balancing

Consistent hashing load balancing

1 Why do we need a hash algorithm

Solve the same user access to the server, the access is a matter of different servers

Scene: session cluster caused no synchronization

When a user accesses server A, the server A saved session this server, but when the next time you visit, the load balancing algorithm may be considered to a different server B, server B, without the user's session, will It requires users to log in again.

solve:

  1. Redis added, to save the session in redis
  2. Tomcat synchronization session
  3. Consistent hashing algorithm

2 What is consistent hashing algorithm

When a server cluster receives the call request, the request based on information, such as the client ip address, or path request parameter request information hash, a hash value can be derived, it is characterized by the same ip address, or path request and the request hash out parameter values ​​are the same, as long as a method to increase again, this can be mapped to a hash value ip address server, you can use the same request (same address ip, or request path and the request parameters) fall on the same server.

Because the request is initiated by the client (the client different addresses, different request parameters, etc.) endless, so the hash value is infinite, so we can not put all the hash values are mapped onto the server ip All here need to use the hash ring .

3 virtual nodes

  1. Solve the problem of uneven service due to a server hang
  2. Such hash ring smoother

Then when a server hang, then, will result in uneven of server services

Will find a range of direct and ip3 ip1 is relatively large, there will be more requests fell on ip1, it was "unfair" to solve this problem need to add virtual nodes , such as:

Wherein, ip2-1, ip3-1 is the virtual node, the processing node can not, but is equivalent to the corresponding server.
In fact, it's just deal with this imbalance of an idea, in fact, even if the hash ring itself is balanced, you can add more virtual nodes to make this ring even more smooth .

The above more hash hash ring, smooth

Just need to find greater than hashcode to a virtual node can be

由于哈希环上的点是有序的,那么采用的数据结构是TreeMap

4 代码实现

public class ServerIps {

    public static final List<String> LIST = (List<String>) Arrays.asList(
            "192.168.0.1",
            "192.168.0.2",
            "192.168.0.3",
            "192.168.0.4",
            "192.168.0.5",
            "192.168.0.6",
            "192.168.0.7",
            "192.168.0.8",
            "192.168.0.9",
            "192.168.0.10"
            );

}

======================================

import java.util.SortedMap;
import java.util.TreeMap;

public class ConsistentHash {

    private static TreeMap<Integer, String> virtualNodes = new TreeMap<>();
    private static final int VIRTUAL_NODES = 160;

    static {
        for(String ip: ServerIps.LIST) {
            for (int i = 0; i < VIRTUAL_NODES; i++) {
                int hash = getHash(ip+i);
                virtualNodes.put(hash, ip);
            }

        }
    }

    private static String getServer(String client) {
        int hash = getHash(client);

        //大于hash,virtualNodes的子树的firstkey
        //tailMap,能获得大于等于hash值的一棵子红黑树
        SortedMap subMap = virtualNodes.tailMap(hash);
        Integer firstKey = null;

        if(subMap == null) {
            firstKey = virtualNodes.firstKey();
        } else {
            firstKey = (Integer) subMap.firstKey();
        }

        return virtualNodes.get(firstKey);
    }

    private static int getHash(String str) {
        final int p = 16777619;
        int hash = (int) 2166136261L;
        for(int i = 0; i < str.length(); i++) 
            hash = (hash ^ str.charAt(i)) * p;
        hash += hash << 13;
        hash ^= hash >> 7;
        hash += hash << 3;
        hash ^= hash >> 17;
        hash += hash << 5;

        if(hash < 0)
            hash = Math.abs(hash);
        return hash;
    }

    public static void main(String[] args) {

        for (int i = 0; i < 12; i++) {
            System.out.println(getServer("client"+i));
        }
    }

}

5 最小活跃数

由于服务的时间并不是固定,如果平均分配服务器有的时候并不合理

比如:
有3个消息,分别请求了A、B、C三台服务器,处理的时间依次为3s、2s、1s,当1s后有一个新的请求过来,按道理说应该A服务器来服务,但是C台服务器已经空闲了,所有这样的分配方式有时候并不合理。

解决:
采用最小活跃数,哪台机器服务最少,用哪台机器,当都大致相等的时候可以根据前面的随机、轮询等。

6 算法的魅力

  • 将程序“复杂化”,提升程序效率到极致

Guess you like

Origin www.cnblogs.com/Stephanie-boke/p/12293626.html