说明
半小时白板代码实现一致性哈希Hash算法,这是Intel一次面试题。面试官丢下这个问题和白板,面试官就工作去了。
讲师:李智慧
什么是一致性哈希Hash
一致性哈希是解决分布式缓存中,当扩容的时候,数据不一致的问题。
一致性哈希如何实现?
- 首先建立一个2的32次方环,0~2的32次方-1,首尾相连,构建一个一致性哈希环;
- 把服务器若干个虚拟节点的哈希值,放到这个环上;
- 要计算的哈希值的Key值,也放到环上;
- 从这个Key值,顺时针查找,离它最近的虚拟节点的服务器。
Java实现
package hash;
import java.util.SortedMap;
import java.util.TreeMap;
class Node {
String ipAddress;
public Node(String ipAddress) {
this.ipAddress = ipAddress;
}
}
public class ConsistentHashElegent {
private SortedMap<Integer, Node> hashCircle = new TreeMap<>();
public ConsistentHashElegent(Node[] nodes, int virtualNums) {
// init consistent hash
for (Node node: nodes) {
for (int i = 0; i < virtualNums; i++) {
hashCircle.put(getHash(node.toString() + i), node);
}
}
}
// get consistent node
public Node getConsistentNode(String key) {
int hash = getHash(key);
// validate whether hash is equal to the virtual node hash
if (hashCircle.containsKey(hash)) {
// the right tree of key hash
SortedMap<Integer, Node> tailMap = hashCircle.tailMap(hash);
hash = tailMap.isEmpty()? hashCircle.firstKey() : tailMap.firstKey();
}
return hashCircle.get(hash);
}
/**
* gain hash code from string
* @param str input
* @return
*/
public 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;
return hash;
}
}
更多请参考:
极客大学架构师训练营 系统架构 分布式缓存 一致性哈希 Hash 第9课 听课总结
参考
https://blog.csdn.net/zgpeace/article/details/107092057