[distributed] load balance 03 – Java implementation of consistent hash algorithm

Time:2021-11-29

Load balancing series topics

01 – load balancing Basics

02 consistency hash principle

03 Java implementation of consistent hash algorithm

04 – Java implementation of load balancing algorithm

In this section, let’s look at how to implement a consistent hash framework.

Source code

Normal hash

Let’s first define the hash interface and the simplest JDK implementation:

  • IHash
public interface IHash {

    /**
     *Calculate hash value
     *@ param text
     *@ return result
     * @since 0.0.1
     */
    int hash(String text);

}
  • HashJdk.java
public class HashJdk implements IHash {

    @Override
    public int hash(String text) {
        return text.hashCode();
    }

}

Node definition

Used to define a node:

Some methods are omitted here.

public class Node {

    /**
     *Node name
     * @since 0.0.1
     */
    private String name;

    /**
     *Node IP
     * @since 0.0.1
     */
    private String ip;

    public Node(String name, String ip) {
        this.name = name;
        this.ip = ip;
    }

    public Node(String ip) {
        this(ip, ip);
    }

    //Getter & Setter & toString()
    // equals && hashCode
}

Core implementation

  • IConsistentHashing.java

Interface definition of consistency hash.

public interface IConsistentHashing {

    /**
     *Get the corresponding node
     * @param key key
     *@ return node
     * @since 0.0.1
     */
    Node get(final String key);

    /**
     *Add node
     *@ param node node
     * @return this
     * @since 0.0.1
     */
    IConsistentHashing add(final Node node);

    /**
     *Remove node
     *@ param node node
     * @return this
     * @since 0.0.1
     */
    IConsistentHashing remove(final Node node);

    /**
     *Get node information
     *@ return node
     * @since 0.0.1
     */
    Map<Integer, Node> nodeMap();

}
  • Default implementation
public class ConsistentHashing implements IConsistentHashing {

    /**
     *Number of virtual nodes
     * @since 0.0.1
     */
    private final int virtualNum;

    /**
     *Hash policy
     * @since 0.0.1
     */
    private final IHash hash;

    /**
     *Node map node information
     *
     *Key: node hash
     *Node: node
     * @since 0.0.1
     */
    private final TreeMap<Integer, Node> nodeMap = new TreeMap<>();

    public ConsistentHashing(int virtualNum, IHash hash) {
        this.virtualNum = virtualNum;
        this.hash = hash;
    }

    /**
     *Find the virtual node clockwise along the ring
     * @param key key
     *@ return result
     * @since 0.0.1
     */
    @Override
    public Node get(String key) {
        final int hashCode = hash.hash(key);
        Integer target = hashCode;

        //Processing when not included
        if (!nodeMap.containsKey(hashCode)) {
            target = nodeMap.ceilingKey(hashCode);
            if (target == null && !nodeMap.isEmpty()) {
                target = nodeMap.firstKey();
            }
        }
        return nodeMap.get(target);
    }

    @Override
    public IConsistentHashing add(Node node) {
        //Initialize virtual node
        for (int i = 0; i < virtualNum; i++) {
            int nodeKey = hash.hash(node.toString() + "-" + i);
            nodeMap.put(nodeKey, node);
        }

        return this;
    }

    @Override
    public IConsistentHashing remove(Node node) {
        //Remove virtual node
        //In fact, there is a problem here. If there are hash conflicts, will direct removal be not rigorous enough?
        for (int i = 0; i < virtualNum; i++) {
            int nodeKey = hash.hash(node.toString() + "-" + i);
            nodeMap.remove(nodeKey);
        }

        return this;
    }

    @Override
    public Map<Integer, Node> nodeMap() {
        return Collections.unmodifiableMap(this.nodeMap);
    }

}

Complete code

There are other auxiliary tools such as boot classes.

See for complete codegithub

[distributed] load balance 03 - Java implementation of consistent hash algorithm

reference material

consistent-hashing-redis

consistent-hash-algorithm

ConsistentHash

Java implementation of consistent hash