下面这张图基本可以概括其原理(图片我是复制自其它地方):
自己写了一个简单的实现,帮助理解,代码如下
ConsistentHash代码
/*
* 一个简单的一致性hash算法
*/
public class ConsistentHash {
private HashPair[] consisentArray;
private final int NUMBER_HASH = 50;
// 所有服务器节点、value值映射到hash的范围大小
private final int HASH_SIZE = 1 << 20;
// 将服务器的节点进行映射,使用String类型模拟
private void setCurServer(List<String> nodes) {
int serverNum = nodes.size();
consisentArray = new HashPair[serverNum * NUMBER_HASH];
for (int i = 0; i < serverNum * NUMBER_HASH; i++) {
consisentArray[i] = new HashPair();
}
int curPos = 0;
int nIndex = 0;
for (String node : nodes) {
int hashcode = SimpleHashUtil.hash_1(node, HASH_SIZE);
// 这里使用最简单的方法进行按组设置
for (int i = 0; i < consisentArray.length / nodes.size(); i++) {
consisentArray[curPos].setHash(Math.abs(hashcode));
consisentArray[curPos].setIndex(nIndex);
curPos++;
}
nIndex++;
}
// 重新排序
Arrays.sort(consisentArray);
}
// 获取某一个值的服务器index
public int getServerIndex(String key) {
int hashcode = Math.abs(SimpleHashUtil.hash_1(key, HASH_SIZE));
int nIndex = Arrays.binarySearch(consisentArray, hashcode);
if (nIndex < 0) {
nIndex = Math.abs(nIndex) - 1;
}
if (nIndex >= consisentArray.length) {
nIndex = consisentArray.length - 1;
}
return consisentArray[nIndex].getIndex();
}
}
其中的HashPair代码如下:
public class HashPair implements Comparable<Object> {
private int hash;
private int index;
public HashPair() {
}
public HashPair(int hash) {
this.hash = hash;
}
public int compareTo(Object o) {
int num = 0;
if (o instanceof HashPair) {
num = ((HashPair) o).getHash();
} else if (o instanceof Integer) {
num = ((Integer) o).intValue();
}
if (this.hash < num) {
return -1;
} else if (this.hash > num) {
return 1;
} else {
return 0;
}
}
}