共计 2511 个字符,预计需要花费 7 分钟才能阅读完成。
这篇文章给大家介绍一致性哈希算法的 java 实现是怎样的,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
今天我们用 java 来实现一下,一致性哈希算法,重点还是一致性和虚拟节点 2 个方面。
废话少说,直接上代码:
public class ConsistencyHash {
private TreeMap Long, String nodes = null;
private List String shards = new ArrayList String
private int VIRTUAL_NUM = 4;
public void init() {
shards.add(10.10.0.0- 服务器 0
shards.add(10.10.0.1- 服务器 1
shards.add(10.10.0.2- 服务器 2
shards.add(10.10.0.3- 服务器 3
shards.add(10.10.0.4- 服务器 4
nodes = new TreeMap Long, String
for (int i = 0; i shards.size(); i++) {
String shardInfo = shards.get(i);
for (int j = 0; j VIRTUAL_NUM; j++) {
byte[] md5Value = computeMd5( SHARD- + i + -NODE- + j);
long hashCode = hash(md5Value, j);
System.out.println(hashCode);
nodes.put(hashCode, shardInfo);
}
}
Iterator Long iter = nodes.keySet().iterator();
while(iter.hasNext()){
Long key = iter.next();
String obj = (String)nodes.get(key);
System.out.println(String.valueOf(key) + : + obj);
}
}
public Object getShardInfo(long hash) {
Long key = hash;
SortedMap Long, String tailMap = nodes.tailMap(key);
if (tailMap.isEmpty()) {
key = nodes.firstKey();
} else {
key = tailMap.firstKey();
}
return nodes.get(key);
}
public void printMap() {
System.out.println(nodes);
}
public long hash(byte[] digest, int nTime) {
long rv = ((long) (digest[3 + nTime * 4] 0xFF) 24) | ((long) (digest[2 + nTime * 4] 0xFF) 16)
| ((long) (digest[1 + nTime * 4] 0xFF) 8) | (digest[0 + nTime * 4] 0xFF);
return rv 0xffffffffL; /* Truncate to 32-bits */
}
/**
* Get the md5 of the given key. 计算 MD5 值
*/
public byte[] computeMd5(String k) {
MessageDigest md5;
try {
md5 = MessageDigest.getInstance(MD5
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(MD5 not supported , e);
}
md5.reset();
byte[] keyBytes = null;
try {
keyBytes = k.getBytes(UTF-8
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(Unknown string : + k, e);
}
md5.update(keyBytes);
byte[] res = md5.digest();
return res;
}
public static void main(String[] args) {
Random ran = new Random();
ConsistencyHash hash = new ConsistencyHash();
hash.init();
hash.printMap();
for (int i = 0; i 256; i++) {
int randomVirtualServer = ran.nextInt(hash.VIRTUAL_NUM);
byte[] md5Value = hash.computeMd5(String.valueOf(i));
long hashValue = hash.hash(md5Value, randomVirtualServer);
String serverInfo = (String)hash.getShardInfo(hashValue);
System.out.println(serverInfo);
}
}
}
环境:假定为 5 台真实服务器,每台真实服务器对应 4 个虚拟节点,这样就是 20 个服务节点。
首先是 init() 方法,该方法就是把 20 个服务节点,分布在一个 2^32 的圆环上。这里分为 2 步,首先根据形如“SHARD-2-NODE-3”这样的字符串得到一个 16 个长度的 byte 数组;之后根据这个 byte 数组获得 2^32 范围内的哈希值。
然后假定 256 个数据对象,我们需要为他们分别找到一个服务节点。
根据一致性的定义,我们需要根据这 256 个数据对象,分别一个 2^32 范围内的哈希值,为了方便起见,我们采取和服务节点一致的方法。
之后,在 getShardInfo 方法当中,在圆环内,为他们寻找各自所属的服务节点。
关于一致性哈希算法的 java 实现是怎样的就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。