java实现一致性hash算法实例代码

一致性hash算法java版本简单实现

package com.java4all.grouth.consistent;

import java.util.LinkedList;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 一致性hash算法java简易实现
 * @author IT云清
 * 参考:https://blog.csdn.net/zhanglu0223/article/details/100579254
 */
public class ConsistentHash {

 private static final Logger LOGGER = LoggerFactory.getLogger(ConsistentHash.class);

 /**
  * 虚拟节点个数
  * 每个真实节点对应的虚拟节点个数
  */
 private static final int VIRTUAL_NUM = 5;

 /**
  * 虚拟节点
  * eg:<656715414,192.168.1.1&&VN3>
  * 真实节点数量一般偏少,引入虚拟节点来平衡
  * 每个真实节点对应多个虚拟节点,这样每个节点尽可能在hash环上均匀分布,可以根据虚拟节点找到真实节点
  */
 private static SortedMap<Integer,String> shards = new TreeMap<>();

 /**
  * 真实节点
  */
 private static List<String> realNodes = new LinkedList<>();

 /**
  * 模拟初始节点
  */
 private static String[] servers = {"116.116.1.1", "116.116.1.2", "116.116.1.3", "116.116.1.5", "116.116.1.6"};

 /**
  * 初始化虚拟节点
  */
 static {
  for (String server : servers) {
   realNodes.add(server);
   LOGGER.info("添加真实节点{}",server);
   for(int i = 0;i < VIRTUAL_NUM; i ++){
    String virtualNode = server + "&&VN" + i;
    int hash = getHash(virtualNode);
    shards.put(hash,virtualNode);
    LOGGER.info("添加虚拟节点{},hash为{}",virtualNode,hash);
   }
  }
 }

 public static void main(String[]args){
  test2();
 }

 public static void test2(){
  //测试定位node
  LOGGER.info(getSever("aa"));
  LOGGER.info(getSever("涨三"));
  LOGGER.info(getSever("num_19120000"));
  LOGGER.info(getSever("num_19120000"));
  LOGGER.info("------------------");
  //测试添加节点
  addNode("192.192.116.1");
  addNode("192.192.116.2");
  LOGGER.info("------------------");
  //测试删除节点
  delNode("116.116.1.1");
 }
 /**
  * 获取真实节点ip
  * @param str 字符串
  * @return
  */
 public static String getSever(String str){
  //计算hash
  int hash = getHash(str);
  Integer key = null;
  //寻找最近的虚拟node
  SortedMap<Integer, String> tailMap = shards.tailMap(hash);
  //获取在hash环上 右侧最近的虚拟节点的key
  key = tailMap.isEmpty() ? shards.lastKey() : tailMap.firstKey();
  //根据hash获取虚拟节点
  String virtualNode = shards.get(key);
  //返回虚拟节点的真实ip
  return virtualNode.substring(0,virtualNode.indexOf("&&"));
 }

 /**
  * 添加节点
  * @param node
  */
 public static void addNode(String node){
  if(!realNodes.contains(node)){
   realNodes.add(node);
   LOGGER.info("新增真实节点上线,{}",node);
   for(int i = 0;i < VIRTUAL_NUM;i ++){
    String virtualNode = node + "&&VN" + i;
    int hash = getHash(virtualNode);
    shards.put(hash,virtualNode);
    LOGGER.info("新增虚拟节点{},hash为{}",virtualNode,hash);
   }
  }

 }

 /**
  * 删除节点
  * @param node
  */
 public static void delNode(String node){
  if(realNodes.contains(node)){
   //下线真实节点
   realNodes.remove(node);
   LOGGER.info("真实节点下线,{}",node);
   for(int i = 0;i < VIRTUAL_NUM; i++){
    String virtualNode = node + "&&VN" + i;
    int hash = getHash(virtualNode);
    //移除虚拟节点
    shards.remove(hash);
    LOGGER.info("下线虚拟节点{},hash为{}",virtualNode,hash);
   }
  }
 }

 /**
  * FNV1_32_HASH算法
  * @param str 任意字符串
  * @return 返回int类型的hash值
  */
 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;
 }
}

到此这篇关于java实现一致性hash算法的文章就介绍到这了,更多相关java实现一致性hash算法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • java遍历HashMap简单的方法

    本文实例讲述了java遍历HashMap简单的方法.分享给大家供大家参考.具体实现方法如下: import java.util.HashMap; import java.util.Iterator; import java.util.Set; public class HashSetTest { public static void main(String[] args) { HashMap map = new HashMap(); map.put("a", "aa"

  • JAVA HashMap详细介绍和示例

    第1部分 HashMap介绍HashMap简介HashMap 是一个散列表,它存储的内容是键值对(key-value)映射.HashMap 继承于AbstractMap,实现了Map.Cloneable.java.io.Serializable接口.HashMap 的实现不是同步的,这意味着它不是线程安全的.它的key.value都可以为null.此外,HashMap中的映射不是有序的.HashMap 的实例有两个参数影响其性能:"初始容量" 和 "加载因子".容量

  • Java集合之HashMap用法详解

    本文实例讲述了Java集合之HashMap用法.分享给大家供大家参考,具体如下: HashMap是最常用的Map集合,它的键值对在存储时要根据键的哈希码来确定值放在哪里. HashMap 中作为键的对象必须重写Object的hashCode()方法和equals()方法 import java.util.Map; import java.util.HashMap; public class lzwCode { public static void main(String [] args) { M

  • Java中HashMap和Hashtable及HashSet的区别

    Hashtable类   Hashtable继承Map接口,实现一个key-value映射的哈希表.任何非空(non-null)的对象都可作为key或者value. 添加数据使用put(key,value),取出数据使用get(key),这两个基本操作的时间开销为常数. Hashtable通过initial   capacity和load   factor两个参数调整性能.通常缺省的load   factor   0.75较好地实现了时间和空间的均衡.增大load   factor可以节省空间但

  • java HashMap通过value反查key的代码示例

    复制代码 代码如下: import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Set;public class MapValueGetKey {  public static void main(String[] args) {    Map map = new HashMap<>();    map.put(1,&qu

  • Java8 HashMap的实现原理分析

    前言:Java8之后新增挺多新东西,在网上找了些相关资料,关于HashMap在自己被血虐之后痛定思痛决定整理一下相关知识方便自己看.图和有些内容参考的这个文章:http://www.jb51.net/article/80446.htm HashMap的存储结构如图:一个桶(bucket)上的节点多于8个则存储结构是红黑树,小于8个是单向链表. 1:HashMap的一些属性 public class HashMap<k,v> extends AbstractMap<k,v> impl

  • Java常用HASH算法总结【经典实例】

    本文实例讲述了Java常用HASH算法.分享给大家供大家参考,具体如下: /** * Hash算法大全<br> * 推荐使用FNV1算法 * @algorithm None * @author Goodzzp 2006-11-20 * @lastEdit Goodzzp 2006-11-20 * @editDetail Create */ public class HashAlgorithms { /**//** * 加法hash * @param key 字符串 * @param prime

  • Java中HashMap和TreeMap的区别深入理解

    首先介绍一下什么是Map.在数组中我们是通过数组下标来对其内容索引的,而在Map中我们通过对象来对对象进行索引,用来索引的对象叫做key,其对应的对象叫做value.这就是我们平时说的键值对. HashMap通过hashcode对其内容进行快速查找,而 TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定的). HashMap 非线程安全 TreeMap 非线程安全 线程安全 在Java里,线程安全一般体

  • java实现一致性hash算法实例代码

    一致性hash算法java版本简单实现 package com.java4all.grouth.consistent; import java.util.LinkedList; import java.util.List; import java.util.SortedMap; import java.util.TreeMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 一致性hash算法java简易实现 * @

  • Java创建树形结构算法实例代码

    在JavaWeb的相关开发中经常会涉及到多级菜单的展示,为了方便菜单的管理需要使用数据库进行支持,本例采用相关算法讲数据库中的条形记录进行相关组装和排序讲菜单组装成树形结构. 首先是需要的JavaBean import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; import j

  • Java语言Consistent Hash算法学习笔记(代码示例)

    本文研究的主要是ConsistentHashing算法代码. 一致性哈希(Consistent Hash) 协议简介 一致性哈希算法在1997年由麻省理工学院提出(参见0),设计目标是为了解决因特网中的热点(Hot pot)问题,初衷和CARP十分类似.一致性哈希修正了CARP使用的简单哈希算法带来的问题,使得DHT可以在P2P环境中真正得到应用. 哈希算法 一致性哈希提出了在动态变化的Cache环境中,哈希算法应该满足的4个适应条件: 平衡性(Balance) 平衡性是指哈希的结果能够尽可能分

  • Java使用异或运算实现简单的加密解密算法实例代码

    Java简单的加密解密算法,使用异或运算 实例1: package cn.std.util; import java.nio.charset.Charset; public class DeEnCode { private static final String key0 = "FECOI()*&<MNCXZPKL"; private static final Charset charset = Charset.forName("UTF-8"); pr

  • Java性能优化之数据结构实例代码

    -举例(学生排课)- 正常思路的处理方法和优化过后的处理方法: 比如说给学生排课.学生和课程是一个多对多的关系. 按照正常的逻辑 应该有一个关联表来维护 两者之间的关系. 现在,添加一个约束条件用于校验.如:张三上学期学过的课程,在排课的时候不应该再排这种课程. 所以需要出现一个约束表(即:历史成绩表). 即:学生选课表,需要学生成绩表作为约束. -方案一:正常处理方式- 当一个学生进行再次选课的时候.需要查询学生选课表看是否已经存在. 即有如下校验: //查询 学生code和课程code分别为

  • PHP实现的一致性HASH算法示例

    本文实例讲述了PHP实现的一致性HASH算法.分享给大家供大家参考,具体如下: <?php // +---------------------------------------------------------------------- // | Perfect Is Shit // +---------------------------------------------------------------------- // | PHP实现:一致性HASH算法 // +--------

  • 基于一致性hash算法 C++语言的实现详解

    一致性hash算法实现有两个关键问题需要解决,一个是用于结点存储和查找的数据结构的选择,另一个是结点hash算法的选择. 首先来谈一下一致性hash算法中用于存储结点的数据结构.通过了解一致性hash的原理,我们知道结点可以想象为是存储在一个环形的数据结构上(如下图),结点A.B.C.D按hash值在环形分布上是有序的,也就是说结点可以按hash值存储在一个有序的队列里.如下图所示,当一个hash值为-2^20的请求点P查找路由结点时,一致性hash算法会按hash值的顺时针方向路由到第一个结点

  • Java编程实现A*算法完整代码

    前言 A*搜寻算法俗称A星算法.这是一种在图形平面上,有多个节点的路径,求出最低通过成本的算法.常用于游戏中 通过二维数组构建的一个迷宫,"%"表示墙壁,A为起点,B为终点,"#"代表障碍物,"*"代表算法计算后的路径 本文实例代码结构: % % % % % % % % o o o o o % % o o # o o % % A o # o B % % o o # o o % % o o o o o % % % % % % % % =======

  • Java Chaos Game噪声游戏实例代码

    [简介] 最近一直在读<深奥的简洁>,里面有一章介绍了几种使用噪声产生分形图的方法,感觉很有意思,于是尝试使用计算机模拟了一下,效果还不错(噪声法比传统迭代法在编程上好实现一些,后来发现这类算法还不少,搜索chaosgame可以找到更多). [Sierpinski三角形的噪声产生法] 在这些噪声游戏中,Sierpinski(谢尔宾斯基)三角形的生成规则可谓是最简单的: 1.在平面上选取三个点,标记为1.2.3,作为大三角形的顶点. 2.选择其中一点,作为"当前点"(比如选择

  • PHP实现的一致性Hash算法详解【分布式算法】

    本文实例讲述了PHP实现的一致性Hash算法.分享给大家供大家参考,具体如下: 一致性哈希算法是分布式系统中常用的算法,为什么要用这个算法? 比如:一个分布式存储系统,要将数据存储到具体的节点(服务器)上, 在服务器数量不发生改变的情况下,如果采用普通的hash再对服务器总数量取模的方法(如key%服务器总数量),如果期间有服务器宕机了或者需要增加服务器,问题就出来了. 同一个key经过hash之后,再与服务器总数量取模的结果跟之前的结果会不一样,这就导致了之前保存数据的丢失.因此,引入了一致性

随机推荐