public class ConsistentHashBalance {
public ConsistentHashBalance(int virtualNum) {
this.virtualNum = virtualNum;
}
* 物理节点
*/
private List<CacheNode> cacheNodeList = new ArrayList<CacheNode>();
* 虚拟节点
*/
private TreeMap<Integer, CacheNode> virtualNodeMap = new TreeMap<Integer, CacheNode>();
* 虚拟节点个数
*/
private int virtualNum;
* 添加节点
*
* @param node
*/
public void addServer(CacheNode node) {
cacheNodeList.add(node);
for (int i = 0; i < this.virtualNum; i++) {
String nodeName = StrUtil.format("{}-VM-{}", node.getIp(), i);
int hash = this.getHash(nodeName);
virtualNodeMap.put(hash, node);
}
}
* 获取节点
*
* @param cacheKey
* @return
*/
public CacheNode getNode(String cacheKey) {
int hash = getHash(cacheKey);
SortedMap<Integer, CacheNode> tailMap = virtualNodeMap.tailMap(hash);
Integer key = tailMap.isEmpty() ? virtualNodeMap.firstKey() : tailMap.firstKey();
return virtualNodeMap.get(key);
}
* Hash 算法
*
* @param key
* @return
*/
private int getHash(String key) {
final int p = 16777619;
int hash = (int) 2166136261L;
for (int i = 0; i < key.length(); i++) {
hash = (hash ^ key.charAt(i)) * p;
}
hash += hash << 13;
hash ^= hash >> 7;
hash += hash << 3;
hash ^= hash >> 17;
hash += hash << 5;
if (hash < 0) {
hash = Math.abs(hash);
}
return hash;
}
public List<CacheNode> getCacheNodeList() {
return cacheNodeList;
}
public int getVirtualNum() {
return virtualNum;
}
}
public class CacheNode {
public CacheNode(String ip, int port) {
this.ip = ip;
this.port = port;
}
private String ip;
private int port;
private List<String> data = new ArrayList<String>();
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public List<String> getData() {
return data;
}
public void setData(List<String> data) {
this.data = data;
}
}
public class MathUtils {
* 求标准差
*
* @param x
* @return
*/
public static double standardDiviation(int[] x) {
int m = x.length;
int sum = 0;
for (int i = 0; i < m; i++) {
sum += x[i];
}
int dAve = sum / m;
int dVar = 0;
for (int i = 0; i < m; i++) {
dVar += (x[i] - dAve) * (x[i] - dAve);
}
return Math.sqrt(dVar / m);
}
}
public class Main {
public static void main(String[] args) {
ConsistentHashBalance hashBalance = new ConsistentHashBalance(50);
for (int i = 1; i <= 10; i++) {
hashBalance.addServer(new CacheNode("192.168.1." + i, 6379));
}
for (int i = 0; i < 1000000; i++) {
String key = IdUtil.objectId();
CacheNode node = hashBalance.getNode(key);
node.getData().add(key);
}
int serverSize = hashBalance.getCacheNodeList().size();
int[] counters = new int[serverSize];
List<CacheNode> cacheNodeList = hashBalance.getCacheNodeList();
for (int i = 0; i < serverSize; i++) {
counters[i] = cacheNodeList.get(i).getData().size();
}
double standardDeviation = MathUtils.standardDiviation(counters);
System.out.println(StrUtil.format("物理节点 : {}个, 虚拟节点 : {}个, 标准差 : {}", serverSize, hashBalance.getVirtualNum(), standardDeviation));
hashBalance.getCacheNodeList().forEach(x -> {
System.out.println(StrUtil.format("{} : {}", x.getIp(), x.getData().size()));
});
}
}
评论