一致性Hash原理這里不再介紹了,下面是一個(gè)簡(jiǎn)單版的實(shí)現(xiàn)方案。
1、MurmurHashUtils
package com.jane.pos.sync.utils;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/**
* 利用murmurHash實(shí)現(xiàn)高性能的低碰撞的純數(shù)字hash值
*/
public class MurmurHashUtils {
private static final String UTF_8 = "UTF-8";
public static long hash74A(byte[] data, int seed) {
return hash74A(ByteBuffer.wrap(data), seed);
}
public static long hash74A(ByteBuffer buf, int seed) {
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() >= 8) {
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);
// for big-endian version, do this first:
// finish.position(8-buf.remaining());
finish.put(buf).rewind();
h ^= finish.getLong();
h *= m;
}
h ^= h >>> r;
h *= m;
h ^= h >>> r;
buf.order(byteOrder);
return h;
}
public static long hash(byte[] key) {
return hash74A(key, 0x1234ABCD);
}
public static long hash(String key) {
return hash(encode(key));
}
/**
* Long轉(zhuǎn)換成無(wú)符號(hào)長(zhǎng)整型(C中數(shù)據(jù)類型)
*/
public static BigDecimal readUnsignedLong(long value) {
if (value >= 0)
return new BigDecimal(value);
long lowValue = value & 0x7fffffffffffffffL;
return BigDecimal.valueOf(lowValue).add(BigDecimal.valueOf(Long.MAX_VALUE)).add(BigDecimal.valueOf(1));
}
/**
* 返回?zé)o符號(hào)murmur hash值
*/
public static BigDecimal hashUnsigned(String key) {
return readUnsignedLong(hash(key));
}
public static BigDecimal hashUnsigned(byte[] key) {
return readUnsignedLong(hash(key));
}
private static byte[] encode(String data) {
try {
return data.getBytes(UTF_8);
} catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException(e);
}
}
}
2、HashUtils
package com.jane.pos.sync.utils;
import java.math.BigDecimal;
import java.util.*;
public class HashUtils {
/**
* 真實(shí)節(jié)點(diǎn)虛擬化,為了節(jié)點(diǎn)分布均衡
* @param realNodes 真實(shí)節(jié)點(diǎn)列表
* @param inventedNum 每個(gè)節(jié)點(diǎn)虛擬的節(jié)點(diǎn)個(gè)數(shù)
* @param hashList 用數(shù)組模擬hash環(huán)
* @return
*/
public static Map inventedNodes(String[] realNodes, int inventedNum, List hashList) {
//虛擬點(diǎn)和真實(shí)節(jié)點(diǎn)的對(duì)應(yīng)關(guān)系
Map map = new HashMap<>();
if(realNodes.length > 0) {
for (String node : realNodes) {
for(int i = 1; i <= inventedNum; i++) {
BigDecimal hashCode = MurmurHashUtils.hashUnsigned(node + i);
map.put(hashCode, node);
//組建hash值數(shù)組,模擬hash環(huán)
hashList.add(hashCode);
}
}
}
return map;
}
/**
* 根據(jù)key獲取固定的一致性節(jié)點(diǎn)
* @param realNodes 真實(shí)節(jié)點(diǎn)
* @param inventedNum 虛擬的節(jié)點(diǎn)數(shù)量
* @param key hash的key,這個(gè)key對(duì)應(yīng)一個(gè)固定的唯一的真實(shí)節(jié)點(diǎn)
* @return
*/
public static String getFixedOnlyNode(String[] realNodes, int inventedNum, String key) {
List hashList = new ArrayList<>();
Map map = inventedNodes(realNodes, inventedNum, hashList);
//hash數(shù)組排序
Collections.sort(hashList);
BigDecimal findHash = MurmurHashUtils.hashUnsigned(key);
for(BigDecimal item : hashList){
//第一個(gè)大的節(jié)點(diǎn),即為要的節(jié)點(diǎn)
if(item.compareTo(findHash) == 1 ) {
return map.get(item);
}
}
//未命中的key,對(duì)節(jié)點(diǎn)取余當(dāng)作下標(biāo),獲取真實(shí)節(jié)點(diǎn)
return map.get(findHash.divideAndRemainder(BigDecimal.valueOf(hashList.size()))[1]);
}
}
3、啟動(dòng)文件
public static void main(String[] args) throws InterruptedException {
String storeNo = "store";
String[] nodes = {"tag01","tag02","tag03","tag04","tag05"};
for (int i = 0; i <= 10; i++){
String key = storeNo + i;
for (int j = 0; j <= 10; j++) {
String node = HashUtils.getFixedOnlyNode(nodes, 10, key);
System.out.println(key + "----" + node);
}
}
}
4、結(jié)果
store0----tag01
store0----tag01
store0----tag01
store0----tag01
store0----tag01
store0----tag01
store0----tag01
store0----tag01
store0----tag01
store0----tag01
store0----tag01
store1----tag03
store1----tag03
store1----tag03
store1----tag03
store1----tag03
store1----tag03
store1----tag03
store1----tag03
store1----tag03
store1----tag03
store1----tag03
store2----tag01
store2----tag01
store2----tag01
store2----tag01
store2----tag01
store2----tag01
store2----tag01
store2----tag01
store2----tag01
store2----tag01
store2----tag01
store3----tag01
store3----tag01
store3----tag01
store3----tag01
store3----tag01
store3----tag01
store3----tag01
store3----tag01
store3----tag01
store3----tag01
store3----tag01
store4----tag02
store4----tag02
store4----tag02
store4----tag02
store4----tag02
store4----tag02
store4----tag02
store4----tag02
store4----tag02
store4----tag02
store4----tag02
store5----tag05
store5----tag05
store5----tag05
store5----tag05
store5----tag05
store5----tag05
store5----tag05
store5----tag05
store5----tag05
store5----tag05
store5----tag05
store6----tag01
store6----tag01
store6----tag01
store6----tag01
store6----tag01
store6----tag01
store6----tag01
store6----tag01
store6----tag01
store6----tag01
store6----tag01
store7----tag05
store7----tag05
store7----tag05
store7----tag05
store7----tag05
store7----tag05
store7----tag05
store7----tag05
store7----tag05
store7----tag05
store7----tag05
store8----tag05
store8----tag05
store8----tag05
store8----tag05
store8----tag05
store8----tag05
store8----tag05
store8----tag05
store8----tag05
store8----tag05
store8----tag05
store9----tag02
store9----tag02
store9----tag02
store9----tag02
store9----tag02
store9----tag02
store9----tag02
store9----tag02
store9----tag02
store9----tag02
store9----tag02
store10----tag03
store10----tag03
store10----tag03
store10----tag03
store10----tag03
store10----tag03
store10----tag03
store10----tag03
store10----tag03
store10----tag03
store10----tag03
新聞標(biāo)題:基于murmurhash+List實(shí)現(xiàn)一致性Hash
本文URL:
http://weahome.cn/article/jgcgdd.html