java一致性hash_一致性Hash Java实现版

package test;

import java.io.UnsupportedEncodingException;

import java.security.MessageDigest;

import java.security.NoSuchAlgorithmException;

import java.util.ArrayList;

import java.util.List;

import java.util.Random;

import java.util.SortedMap;

import java.util.TreeMap;

public class ConsistencyHash {

private TreeMap nodes = null;

//真实服务器节点信息

private List shards = new ArrayList();

//设置虚拟节点数目

private int VIRTUAL_NUM = 4;

/**

* 初始化一致环

*/

public void init() {

shards.add("192.168.0.0-服务器0");

shards.add("192.168.0.1-服务器1");

shards.add("192.168.0.2-服务器2");

shards.add("192.168.0.3-服务器3");

//shards.add("192.168.0.4-服务器4");

nodes = new TreeMap();

for(int i=0; i

Object shardInfo = shards.get(i);

for(int j=0; j

nodes.put(hash(computeMd5("SHARD-" + i + "-NODE-" + j),j), shardInfo);

}

}

}

/**

* 根据key的hash值取得服务器节点信息

* @param hash

* @return

*/

public Object getShardInfo(long hash) {

Long key = hash;

SortedMap 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);

}

/**

* 根据2^32把节点分布到圆环上面。

* @param digest

* @param nTime

* @return

*/

public long hash(byte[] digest, int nTime) {

long rv = ((long) (digest[3+nTime*4] & 0xFF) <

| ((long) (digest[2+nTime*4] & 0xFF) <

| ((long) (digest[1+nTime*4] & 0xFF) <

| (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);

return md5.digest();

}

public static void main(String[] args) {

Random ran = new Random();

ConsistencyHash hash = new ConsistencyHash();

hash.init();

hash.printMap();

//循环50次,是为了取50个数来测试效果,当然也可以用其他任何的数据来测试

for(int i=0; i<50; i++) {

System.out.println(hash.getShardInfo(hash.hash(hash.computeMd5(String.valueOf(i)),ran.nextInt(hash.VIRTUAL_NUM))));

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值