一致性哈希算法 Java 实现

用户头像
dapaul
关注
发布于: 2020 年 07 月 09 日

一致性哈希算法是当前较主流的分布式哈希表协议之一,它对简单哈希算法进行了修正,解决了热点(hotPot)问题。



一致性哈希算法



基于虚拟节点的一致性哈希算法



一致性哈希算法Java实现

基于虚拟节点的一致性哈希算法实现。

public class ConsistentHash {

private List<String> nodeList;

private int virtualNodeDepth;

private SortedMap<Integer, String> nodeMap = new TreeMap<>();

public ConsistentHash(List<String> nodeList) {
this(nodeList, 10);
}

public ConsistentHash(List<String> nodeList, int virtualNodeDepth) {
this.nodeList = nodeList;
this.virtualNodeDepth = virtualNodeDepth;
if (virtualNodeDepth < 1) {
this.virtualNodeDepth = 1;
}
this.init();
}

public String doHash(String key) {
int hashValue = getHash(key);
SortedMap<Integer, String> subMap = nodeMap.tailMap(hashValue);
String virtualNode;
if(subMap.isEmpty()){
Integer i = nodeMap.firstKey();
virtualNode = nodeMap.get(i);
}else{
Integer i = subMap.firstKey();
virtualNode = subMap.get(i);
}
if(!StringUtils.isEmpty(virtualNode)){
return virtualNode.substring(0, virtualNode.indexOf("##"));
}
return null;

}

private 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;
}

private void init() {
String virtualNodeKey;
for (String node : nodeList) {
for (int index = 0; index < virtualNodeDepth; index++) {
virtualNodeKey = node + "##" + index;
int hashValue = getHash(virtualNodeKey);
nodeMap.put(hashValue, virtualNodeKey);
}
}
}
}



计算标准差:

public class StandardDeviation {

private List<Integer> numbers;

public StandardDeviation(List<Integer> numbers) {
this.numbers = numbers;
}

public double getStandardDevition() {
double sum = 0;
int num = numbers.size();
for (int i = 0; i < num; i++) {
double average = (double) numbers.get(i) - getAverage();
sum += Math.sqrt((average * average));
}
return (sum / (num - 1));
}

public double getAverage() {
int sum = 0;
int num = numbers.size();
for (int i = 0; i < num; i++) {
sum += numbers.get(i);
}
return (double) (sum / num);
}
}



测试类:

public static final void main(String[] args) {
List<String> nodeList = new ArrayList<>();
nodeList.add("192.168.1.2");
nodeList.add("192.168.1.3");
nodeList.add("192.168.1.5");
nodeList.add("192.168.1.6");
ConsistentHash consistentHash = new ConsistentHash(nodeList);

Map<String, Integer> result = new HashMap<>();
for (int index = 0; index < 1000000; index++) {
String nodeKey = consistentHash.doHash(String.valueOf(index));
Integer count = result.get(nodeKey);
if (count == null) {
count = 1;
} else {
count++;
}
result.put(nodeKey, count);
}
System.out.println("result : " + result);

List<Integer> numbers = new ArrayList<>();
for (Map.Entry<String, Integer> entry : result.entrySet()) {
numbers.add(entry.getValue());
}

StandardDeviation standardDeviation = new StandardDeviation(numbers);
double standardDevition = standardDeviation.getStandardDevition();
System.out.println("standardDevition : " + standardDevition);
}



结果是:

result : {192.168.1.3=206917, 192.168.1.2=169495, 192.168.1.5=237154, 192.168.1.6=386434}
standardDevition : 90956.0



用户头像

dapaul

关注

还未添加个人签名 2018.09.18 加入

还未添加个人简介

评论

发布
暂无评论
一致性哈希算法Java实现