一致性哈希
发布于: 2020 年 07 月 05 日
主要数据结构:
1、使用一个treeMap保存所有节点
2、每个节点内部使用hashMap保存数据值
实现方案:
创建hash环上的节点,保存在一个treeMap里面,key=节点hash值,value=该节点(内部是一个hashmap)
添加虚拟节点,扩充这个节点treeMap,每个节点随机获取key,value为原来的节点,放入treeMap,保证分布足够均匀
获取节点时,获取treeMap第一个大于传入key哈希值的第一个节点
从节点内部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
版权声明: 本文为 InfoQ 作者【独孤魂】的原创文章。
原文链接:【http://xie.infoq.cn/article/70e32cb306353ed034c286710】。未经作者许可,禁止转载。
独孤魂
关注
还未添加个人签名 2019.04.10 加入
还未添加个人简介
评论