您的位置:首页 > 编程语言 > Java开发

一个简单的一致性哈希算法实现(Java版本)

2016-08-23 10:21 316 查看
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;

/**
* 一致性哈希算法
* @author Administrator
*
* @param <S>
*/
public class Shard<S> {
private TreeMap<Long, S> nodes; //虚拟节点
private List<S> shards;	//真实机器节点
private final int NODE_NUM = 100; //每个机器节点对应的虚拟节点数

public Shard(List<S> shards){
super();
this.shards = shards;
init();

}

private void init() {  //初始化一致性哈希环
// TODO Auto-generated method stub
nodes = new TreeMap<Long, S>();
for(int i =0; i != shards.size(); ++i){ //每个真实机器节点都需要关联虚拟节点
final S shardinfo = shards.get(i);

for(int n = 0; n<NODE_NUM; n++){
//一个真实的机器节点关联的NODE_NUM个虚拟节点
nodes.put(hash("SHARD-"+ i + "-NODE-"+n),  shardinfo);

}

}
}

public S getShardInfo(String key){
SortedMap<Long, S> tail = nodes.tailMap(hash(key));//沿着环的顺时针找到一个虚拟节点
if(tail.size() == 0){
return nodes.get(nodes.firstKey());
}
return tail.get(tail.firstKey());
}
/**
* MurMurHash算法,是非加密的HASH算法,性能很高
* 算法碰撞率低
* @param string
* @return
*/
@SuppressWarnings("static-access")
private Long hash(String key) {
// TODO Auto-generated method stub
ByteBuffer buf = ByteBuffer.wrap(key.getBytes());
int seed = 0x1234ABCD;

ByteOrder byteorder = buf.order();
buf.order(byteorder.LITTLE_ENDIAN);

long m = 0xc6a4a7935bd1e995L;

int r= 47;
long h = seed^(buf.remaining()*m);

long k;
while(buf.remaining() > 0){
k= buf.getLong();
k *= m;
k ^=k>>>r;
k *= m;
h ^= k;
h *= m;

}
if (buf.remaining() >0){
ByteBuffer finish = ByteBuffer.allocate(8).order(ByteOrder.LITTLE_ENDIAN);

finish.put(buf).rewind();
h^= finish.getLong();
h*=m;
}

h ^= h>>>r;
h *= m;
h ^= h>>>r;

buf.order(byteorder);
return h;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: