1、一致性hash算法不使用虛擬結點
package algorithm;
import java.util.SortedMap;
import java.util.TreeMap;
public class ConsistentHashingWithoutVirtualNode {
private static String[] servers = {"192.168.0.0:111", "192.168.0.1:111", "192.168.0.2:111",
"192.168.0.3:111", "192.168.0.4:111"};
private static SortedMap<Integer, String> sortedMap = new TreeMap<>();
static {
for (int i = 0; i < servers.length; i++) {
int hash = getHash(servers[i]);
System.out.println("[" + servers[i] + "]加入集合中, 其Hash值爲" + hash);
sortedMap.put(hash, servers[i]);
}
}
public static int getHash(String str) {
final int p = 167777619;
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;
}
private static String getServer(String node) {
int hash = getHash(node);
SortedMap<Integer, String> subMap = sortedMap.tailMap(hash);
Integer i = subMap.firstKey();
return subMap.get(i);
}
public static void main(String[] args) {
String[] nodes = {"127.0.0.1:1111", "221.226.0.1:2222", "10.211.0.1:3333"};
for (int i = 0; i < nodes.length; i++) {
System.out.println("[" + nodes[i] + "]的hash值爲" + getHash(nodes[i]) + ",被路由到的結點[" + getServer(nodes[i]) + "]");
}
}
}
2、一致性hash算法使用虛擬結點
package algorithm;
import java.util.*;
public class ConsistentHashingWithVirtualNode {
private static String[] servers = {"192.168.0.0:111", "192.168.0.1:111", "192.168.0.2:111"};
private static List<String> realNodes = new LinkedList<>();
private static SortedMap<Integer, String> virtualNodes = new TreeMap<>();
private static final int VIRTUAL_NODES_NUM = 1000;
static {
for (int i = 0; i < servers.length; i++) {
realNodes.add(servers[i]);
}
for (String str : realNodes) {
for (int i = 0; i < VIRTUAL_NODES_NUM; i++) {
String virtualNodeName = str + "&&VN" + i;
int hash = getHash(virtualNodeName);
System.out.println("虛擬節點[" + virtualNodeName + "]被添加, hash值爲" + hash);
virtualNodes.put(hash, virtualNodeName);
}
}
}
public static int getHash(String str) {
final int p = 167777619;
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;
}
private static String getServer(String node) {
int hash = getHash(node);
SortedMap<Integer, String> subMap = virtualNodes.tailMap(hash);
Integer i = null;
String virtualNode = null;
if (subMap == null || subMap.size() == 0) {
i = virtualNodes.firstKey();
virtualNode = virtualNodes.get(i);
} else {
i = subMap.firstKey();
virtualNode = virtualNodes.get(i);
}
return virtualNode.substring(0, virtualNode.indexOf("&&"));
}
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<>();
ArrayList<String> id = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
id.add(UUID.randomUUID().toString().replace("-", ""));
}
for (int i = 0; i < id.size(); i++) {
String aString = getServer(id.get(i));
Integer aInteger = map.get(aString);
if (aInteger == null) {
map.put(aString, 1);
} else {
map.put(aString, aInteger + 1);
}
Set<String> set = map.keySet();
for (String a : set) {
System.out.println("節點【" + a + "】分配到元素個數爲==>" + map.get(a));
}
}
}
}