一致性hash算法的java实现_一致性HASH算法的JAVA实现

文章出处: http://blog.csdn.net/cywosp/article/details/23397179     一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似。一致性哈希修正了CARP使用的简 单

一致性哈希算法是分布式系统中常用的算法。比如,一个分布式的存储系统,要将数据存储到具体的节点上,如果采用普通的hash方法,将数据映射到具体的节点上,如key%N,key是数据的key,Java实现的快速排序算法,分享出来共同学习交流~ public class QuickSort{ public static void main(String args[]){ int[]a={1,5,7,5,7,55,8,7,9,2,1,5}; quickSort(a,0,a.length-1); for(int i:a){ System.out.priN是机器节点数,如果有一个机器加入或退出这个集群,则所有的数据映射都无效了,如果是持久化存储则要做数据迁移,如果是分布式缓存,则其他缓存就失效了。

一致性Hash算法将 value 映射到一个 32 为的 key 值,也即是 0~2^32-1 次方的数值空间;我们可以将这个空间想象成一个首( 0 )尾( 2^32-1 )相接的圆环。

如下图所示:

File?id=ajgj4rnwkrbz_31g72bgcdg_b

package hash;

import java.io.UnsupportedEncodingException;

import java.nio.ByteBuffer;

import java.nio.ByteOrder;

import java.security.MessageDigest;

import java.security.NoSuchAlgorithmException;

import java.util.*;

/**

* Created by IntelliJ IDEA.

* User: test

* Date: 12-5-24

* Time: 下午5:37

* To change this template use File | Settings | File Templates.

*/

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

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、付费专栏及课程。

余额充值