写点什么

一致性哈希

用户头像
独孤魂
关注
发布于: 2020 年 07 月 05 日



主要数据结构

1、使用一个treeMap保存所有节点

2、每个节点内部使用hashMap保存数据值



实现方案

  1. 创建hash环上的节点,保存在一个treeMap里面,key=节点hash值,value=该节点(内部是一个hashmap)

  2. 添加虚拟节点,扩充这个节点treeMap,每个节点随机获取key,value为原来的节点,放入treeMap,保证分布足够均匀

  3. 获取节点时,获取treeMap第一个大于传入key哈希值的第一个节点

  4. 从节点内部hashMap取得值



package com.hyy.datastructure;
import java.util.*;
public class ConsistencyHash {
private SortedMap<Long,Node> nodeMap;
private long maxNode = 2L<<32;
public static void main(String[] args) {
ConsistencyHash conHash = new ConsistencyHash();
String ip[] = new String[]{"10.0.0.1", "10.0.0.2", "10.0.0.3", "10.0.0.4"};
conHash.setNode(ip);
int count = 100;
for(int i=0;i<count;i++){
String key = String.valueOf(i);
conHash.put(key,key);
conHash.getVal(key);
}
}
public String getVal(String key){
//获取节点,再获取节点内的值
Node node = getNode(key);
System.out.println("从"+node.nodeName+"上获取值:"+node.get(key));
return node.get(key);
}
public void put(String key,String val){
getNode(key).put(key,val);
}
/**
* 设置节点数量,每一个节点内部是一个hashMap
* @param keys
*/
public void setNode(String[] keys){
int i = 0;
nodeMap = new TreeMap<>();
for(String str:keys){
Long index = getHashMod(str);
System.out.println("节点"+str+"对应哈希模"+index);
nodeMap.put(index,new Node(str));
}
addVNode();
}
/**
* 添加虚拟节点
*/
public void addVNode(){
//虚拟节点数量
int vCount = 100;
TreeMap<Long,Node> vmap = new TreeMap<>();
nodeMap.forEach((k, v) -> {
vmap.put(k,v);
for(int i=0;i<vCount;i++){
vmap.put(getHashMod(String.valueOf(k+i)),v);
}
});
nodeMap = vmap;
}
/**
* 根据key获取节点
* @param key
* @return
*/
public Node getNode(String key){
Long hash = getHashMod(key);
Node firstNode = null;
Node result = null;
for(Long a: nodeMap.keySet()){
if(firstNode == null){
firstNode = nodeMap.get(a);
}
if(a >hash){
result = nodeMap.get(a);
break;
}
}
if(result == null){
result = firstNode;
}
return result;
}
/**
* 计算环上的哈希取模
* @param key
* @return
*/
public long getHashMod(String key){
return FNVHash1(key)%maxNode;
}
/**
* FNVHash1 算法
* @param key
* @return
*/
public static int FNVHash1(String key) {
byte[] data =key.getBytes();
final int p = 16777619;
int hash = (int)2166136261L;
for(byte b:data)
hash = (hash ^ b) * p;
hash += hash << 13;
hash ^= hash >> 7;
hash += hash << 3;
hash ^= hash >> 17;
hash += hash << 5;
return Math.abs(hash);
}
/**
* 节点类
*/
class Node{
public Node(String name){
this.nodeName = name;
}
public String nodeName;
private Map<String,String> map = new HashMap<>();
public String get(String key){
return map.get(key);
}
public void put(String key,String val){
map.put(key,val);
}
}
}



发布于: 2020 年 07 月 05 日阅读数: 53
用户头像

独孤魂

关注

还未添加个人签名 2019.04.10 加入

还未添加个人简介

评论

发布
暂无评论
一致性哈希