一致性 hash 算法及实现
发布于: 2020 年 09 月 20 日
原理:
先构造一个长度为2的32次方的整数环(这个环被称为一致性Hash环),根据节点名称的Hash值(其分布为[0, 2的32次方-1])将服务器节点放置在这个Hash环上,然后根据数据的Key值计算得到其Hash值(其分布也为[0, 2的32次方-1]),接着在Hash环上顺时针查找距离这个Key值的Hash值最近的服务器节点,完成Key到服务器的映射查找。
实现:
package leetcode;import java.util.*;/** * 一致性Hash算法实现 */public class ConsistencyHash { private static SortedMap<Integer, String> sortedMap = new TreeMap<>(); private List<String> nodeList; public ConsistencyHash(List<String> nodeList) { this.nodeList = nodeList; nodeList.forEach(x -> { addNode(x); }); } private void addNode(String node) { if (node == null) { return; } int hash = getHash(node); sortedMap.put(hash, node); System.out.println("hash = " + hash + " , node = " + node); } /** * 使用FNV1_32_HASH算法计算服务器的Hash值,这里不使用重写hashCode的方法,最终效果没区别 */ private static int getHash(String str) { final int p = 16777619; int hash = (int) 2166136261L; for (int i = 0; i < str.length(); i++) hash = (hash ^ str.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 static String getSever(String node){ // 得到带路由的结点的Hash值 int hash = getHash(node); // 得到大于该Hash值的所有Map SortedMap<Integer,String> sMap = sortedMap.tailMap(hash); // 第一个Key就是顺时针过去离node最近的那个结点 Integer k = sMap.firstKey(); // 返回对应的服务器名称 return sMap.get(k); }}
package leetcode;import java.util.Arrays;import java.util.List;/** * 致性Hash算法调用 */public class Main { public static void main(String[] args) { String[] list = {"192.168.0.0:111", "192.168.0.1:111", "192.168.0.2:111", "192.168.0.3:111", "192.168.0.4:111"}; List<String> nodeList = Arrays.asList(list); //初始化 ConsistencyHash hash = new ConsistencyHash(nodeList); nodeList.forEach(x->{ System.out.println(" server : " + ConsistencyHash.getSever(x)); }); }}
划线
评论
复制
发布于: 2020 年 09 月 20 日阅读数: 45
橙
关注
everything will be alright 2020.04.06 加入
还未添加个人简介
评论