一致性hash算法Consistent Hashing

对于原有hash算法hash%n

so...

1.话不多说直接上代码,原理或详解自行百度即可

import cn.pheker.utils.UtilElapsedTime;
import cn.pheker.utils.UtilLogger;
import cn.pheker.utils.UtilMD5;import java.util.*;/*** <pre>* author    cn.pheker* date      2018/3/19 10:20* email     1176479642@qq.com* desc      一致性哈希算法** </pre>*/
public class ConsistentHashing {private static final long MIN_NODE_NUMBER = 0;private static final int MAX_NODE_NUMBER = Integer.MAX_VALUE;private static int VIRTUAL_NODE_NUMBER;//真实节点private List<Node> realNodes = new LinkedList<Node>();//虚拟节点,hash环private SortedMap<Integer, VNode> circle = new TreeMap<Integer, VNode>();private ConsistentHashing(int vnNumber) {VIRTUAL_NODE_NUMBER = vnNumber;}public static ConsistentHashing build(int vnNumber) {return new ConsistentHashing(vnNumber);}public ConsistentHashing addNode(Map<String,String> ipPorts) {Set<String> ips = ipPorts.keySet();Iterator<String> ipite = ips.iterator();while(ipite.hasNext()){String ip = ipite.next();addNode(ip, ipPorts.get(ip));}return this;}public ConsistentHashing addNode(String ip, int port) {addNode(ip, String.valueOf(port));return this;}public ConsistentHashing addNode(String ip, String port) {Node node = new Node(ip, port);if (!realNodes.contains(node)) {realNodes.add(node);UtilLogger.println("[Node]:"+node.toString()+" Hash:"+node.hashFNV1_32());//生成VIRTUAL_NODE_NUMBER个虚拟节点for (int i = 0; i < VIRTUAL_NODE_NUMBER; i++) {VNode vNode = node.createVNode(i);circle.put(vNode.hashFNV1_32(), vNode);UtilLogger.println("\t[VNode]:"+vNode.toString()+" Hash:"+vNode.hashFNV1_32());}}return this;}public void removeNode(String ip,String port) {Node node = new Node(ip, port);for(int i = 0;i<VIRTUAL_NODE_NUMBER;i++) {VNode vNode = node.createVNode(i);circle.remove(vNode.hashFNV1_32());}circle.remove(node.hashFNV1_32());}public VNode getNode(String ip, int port) {return getNode(ip, String.valueOf(port));}public VNode getNode(String ip, String port) {Node node = new Node(ip, port);int hash = node.hashFNV1_32();if(circle.isEmpty()) return null;SortedMap<Integer, VNode> tailMap = circle.tailMap(hash);int hashKey;if (tailMap.isEmpty()) {hashKey = circle.firstKey();}else {hashKey = tailMap.firstKey();}//顺时针最近节点VNode vNode = circle.get(hashKey);UtilLogger.println(String.format("[%s]:%s ==> [%s]:%s",node.hashFNV1_32(),node,vNode.hashFNV1_32(),vNode));return vNode;}/*** 第个节点都是一个服务器主机*/public class Node {String ip;String port;public Node(String ip, String port) {this.ip = ip;this.port = port;}public String getIp() {return ip;}public void setIp(String ip) {this.ip = ip;}public String getPort() {return port;}public void setPort(String port) {this.port = port;}public VNode createVNode(int vnNumber) {return new VNode(ip, port, vnNumber);}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Node vNode = (Node) o;return Objects.equals(ip, vNode.ip) &&Objects.equals(port, vNode.port);}@Overridepublic String toString() {return ip + ":" + port;}/***使用FNV1_32_HASH算法计算服务器的Hash值,这里不能重写hashCode的方法*/public int hashFNV1_32(){String str = UtilMD5.MD5(this.toString());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 class VNode extends Node{int number;public VNode(String ip, String port,int number) {super(ip, port);this.number = number;}public Node toNode() {return new Node(ip,port);}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;if (!super.equals(o)) return false;VNode vNode = (VNode) o;return number == vNode.number;}@Overridepublic int hashCode() {return Objects.hash(number);}@Overridepublic String toString() {return ip + ":" + port+"#"+number;}}/*** 校验hash分布均匀性* @return*/public float check() {Set<Integer> ks = circle.keySet();int size = ks.size();long sum = 0L;for (int hash : ks) {sum += hash;}double percent = size == MIN_NODE_NUMBER ? MIN_NODE_NUMBER :(100*2*sum/size)/MAX_NODE_NUMBER;return Float.valueOf(String.format("%.2f", percent));}public static void main(String[] args) {UtilElapsedTime.test(() -> {ConsistentHashing ch = ConsistentHashing.build(3);//添加节点UtilLogger.println("------------添加节点----------------");ch.addNode("10.96.74.187", 80);ch.addNode("127.0.0.1", 8080);ch.addNode("243.15.155.0", 2150);ch.addNode("243.15.155.1", 2150);UtilLogger.println("------------是否均匀----------------");UtilLogger.println(ch.check() + "%");//获取节点UtilLogger.println("------------获取节点----------------");ch.getNode("10.96.74.187", 80);ch.getNode("123.1.122.253", 44);ch.getNode("234.67.80.219", 3306);return "耗时计算完成";});}}

2.结果

------------添加节点----------------
[Node]:10.96.74.187:80 Hash:1695118842[VNode]:10.96.74.187:80#0 Hash:1661313686[VNode]:10.96.74.187:80#1 Hash:1283046442[VNode]:10.96.74.187:80#2 Hash:564332117
[Node]:127.0.0.1:8080 Hash:678080562[VNode]:127.0.0.1:8080#0 Hash:1731933288[VNode]:127.0.0.1:8080#1 Hash:1369405387[VNode]:127.0.0.1:8080#2 Hash:200594664
[Node]:243.15.155.0:2150 Hash:1175061629[VNode]:243.15.155.0:2150#0 Hash:134880260[VNode]:243.15.155.0:2150#1 Hash:1677894747[VNode]:243.15.155.0:2150#2 Hash:522817245
[Node]:243.15.155.1:2150 Hash:1305999210[VNode]:243.15.155.1:2150#0 Hash:1193457699[VNode]:243.15.155.1:2150#1 Hash:279279823[VNode]:243.15.155.1:2150#2 Hash:2115663065
------------是否均匀----------------
98.0%
------------获取节点----------------
[1695118842]:10.96.74.187:80 ==> [1731933288]:127.0.0.1:8080#0
[601034131]:123.1.122.253:44 ==> [1193457699]:243.15.155.1:2150#0
[508181784]:234.67.80.219:3306 ==> [522817245]:243.15.155.0:2150#2
[23.104187ms] 耗时计算完成Process finished with exit code 0

3.注意事项

代码中用到了几个工具类UtilMD5,UtilLogger换成自己的即可,UtilElapsedTime用于计算耗时,可以直接去掉。

4.参考链接

对一致性Hash算法,Java代码实现的深入研究
白话解析:一致性哈希算法 consistent hashing

转载于:https://www.cnblogs.com/PheonixHkbxoic/p/8602413.html

一致性hash算法Consistent Hashing相关推荐

  1. 一致性hash算法 - consistent hashing

    参考: http://yacare.iteye.com/blog/1973022 1.   情景分析 前一篇博文分析了HashMap源码,HashMap在许多场景中作为存储数据的不二选择. 但是否使用 ...

  2. 一致性 hash 算法(consistent hashing)

    一致性 hash 算法(consistent hashing) consistent hashing 算法早在 1997 年就在论文 Consistent hashing and random tre ...

  3. 一致性 hash 算法( consistent hashing )

    原文地址:http://blog.csdn.net/sparkliang/article/details/5279393 consistent hashing 算法早在 1997 年就在论文 Cons ...

  4. 转载:一致性 hash 算法( consistent hashing )

    转载:http://blog.csdn.net/sparkliang/article/details/5279393                                           ...

  5. 白话解析:一致性哈希算法 consistent hashing

    在了解一致性哈希算法之前,最好先了解一下缓存中的一个应用场景,了解了这个应用场景之后,再来理解一致性哈希算法,就容易多了,也更能体现出一致性哈希算法的优点,那么,我们先来描述一下这个经典的分布式缓存的 ...

  6. 【转载】一致性哈希算法(consistent hashing)

    一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似.一致性哈希修正了CARP使用的简 单哈 ...

  7. 理解一致性哈希算法(consistent hashing)

    出处:http://blog.csdn.net/cywosp/article/details/23397179     一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法, ...

  8. 《一切皆是映射:代码的本质》一致性哈希算法(consistent hashing)

    一致性Hash算法背景 一致性哈希算法在1997年由麻省理工学院的Karger等人在解决分布式Cache中提出的,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似.一致 ...

  9. 一致性Hash算法(KetamaHash)的c#实现

    Consistent Hashing最大限度地抑制了hash键的重新分布.另外要取得比较好的负载均衡的效果,往往在服务器数量比较少的时候需要增加虚拟节点来保证服务器能均匀的分布在圆环上.因为使用一般的 ...

最新文章

  1. 模型越大,真的越香吗?千亿参数之后是万亿,万亿之后呢?
  2. 用typedef定义函数指针类型(转)
  3. 如何控制dedecms描述的长度?
  4. Android18isalone,全新JAVA开发Android程序员需要掌握的英语单词(很全).doc
  5. 解决gradle下载慢的问题
  6. tensorflow2.0中的Broadcasting用法
  7. Bootstrap 模态对话框
  8. [JavaScript] DOM
  9. Python学习教程:Python自动化测试框架需要学习哪些?
  10. kettle-连接控件
  11. selenium学习一
  12. 链家网页爬虫_R爬虫小白入门:Rvest爬链家网+分析(一)
  13. minio获取上传文件_Springboot集成Minio实现对象存储服务
  14. Okhttp之同步和异步请求简单分析
  15. q 与 blockquote 的区别
  16. php 网站计数器,PHP开源程序通用网站计数器代码分享
  17. JavaScript Lodash 工具库
  18. VTK图像处理之访问图像像素值
  19. 一年级abb式词语并造句_abb词语造句,用ABB词语造句
  20. Jquery--一个form中两个submit事件如何进行区分

热门文章

  1. 编译原理--运行时存储组织(自己看)
  2. The “data“ option should be a function that returns a per-instance value in component definitions.
  3. 2021安徽高考成绩及录取结婚查询,2020安徽高考录取结果查询时间及通知书发放时间...
  4. spingbot 与 activiti 整个 中创建表而找不到表的问题(创建表失败)
  5. 服务器机房项目总结,机房建设项目总结报告.doc
  6. 什么是计算机游戏技术,dlss技术是什么意思有什么用?目前支持dlss的游戏有哪些?...
  7. 7620a路由mysql_MT7620A路由刷DDWRT 及2.4G无线设置经验
  8. 网页输入数据到mysql_为什么用PHP编写的网页中,输入的数据不能插入到Mysql数据库中?...
  9. python相对路径-Python中的绝对路劲和相对路径
  10. javapythonc就业人数比例_P100 统计各年龄段的人数