package com.hash;

import java.util.Collection;

import java.util.SortedMap;

import java.util.TreeMap;

/**

 * 一致性Hash算法

 *

 * @param <T>
节点类型

 */

public class ConsistentHash<T> {


/** Hash计算对象,用于自定义hash算法 */


HashFunc hashFunc;


/** 复制的节点个数 */


private final int numberOfReplicas;


/** 一致性Hash环 */


private final SortedMap<Integer, T> circle = new TreeMap<Integer, T>();

/**


* 构造,使用Java默认的Hash算法


* @param numberOfReplicas 复制的节点个数,增加每个节点的复制节点有利于负载均衡


* @param nodes 节点对象


*/


public ConsistentHash(int numberOfReplicas, Collection<T> nodes) {


this.numberOfReplicas = numberOfReplicas;


this.hashFunc =new HashFunc(){


@Override


public Integer hash(Object key) {


return hashFunc.hash(key);


}};

//初始化节点


for (T node : nodes) {


add(node);


}


}

/**


* 构造


* @param hashFunc hash算法对象


* @param numberOfReplicas 复制的节点个数,增加每个节点的复制节点有利于负载均衡


* @param nodes 节点对象


*/


public ConsistentHash(HashFunc hashFunc, int numberOfReplicas, Collection<T> nodes) {


this.numberOfReplicas = numberOfReplicas;


this.hashFunc = hashFunc;


//初始化节点


for (T node : nodes) {


add(node);


}


}

/**


* 增加节点<br>


* 每增加一个节点,就会在闭环上增加给定复制节点数<br>


* 例如复制节点数是2,则每调用此方法一次,增加两个虚拟节点,这两个节点指向同一Node


* 由于hash算法会调用node的toString方法,故按照toString去重


* @param node 节点对象


*/


public void add(T node) {


for (int i = 0; i < numberOfReplicas; i++) {


circle.put(hashFunc.hash(node.toString() + i), node);


}


}

/**


* 移除节点的同时移除相应的虚拟节点


* @param node 节点对象


*/


public void remove(T node) {


for (int i = 0; i < numberOfReplicas; i++) {


circle.remove(hashFunc.hash(node.toString() + i));


}


}

/**


* 获得一个最近的顺时针节点


* @param key 为给定键取Hash,取得顺时针方向上最近的一个虚拟节点对应的实际节点


* @return 节点对象


*/


public T get(Object key) {


if (circle.isEmpty()) {


return null;


}


int hash = hashFunc.hash(key);


if (!circle.containsKey(hash)) {


SortedMap<Integer, T> tailMap = circle.tailMap(hash);

//返回此映射的部分视图,其键大于等于 hash


hash = tailMap.isEmpty() ? circle.firstKey() : tailMap.firstKey();


}


//正好命中


return circle.get(hash);


}

/**


* Hash算法对象,用于自定义hash算法


*


*/


public interface HashFunc {


public Integer hash(Object key);


}

}

java 一致性哈希类实例 算法的更多相关文章

  1. 深入一致性哈希(Consistent Hashing)算法原理,并附100行代码实现

    转自:https://my.oschina.net/yaohonv/blog/1610096 本文为实现分布式任务调度系统中用到的一些关键技术点分享——Consistent Hashing算法原理和J ...

  2. 一致性哈希(consistent hashing)算法

    文章同步发表在博主的网站朗度云,传输门:http://www.wolfbe.com/detail/201608/341.html 1.背景        我们都知道memcached服务器是不提供分布 ...

  3. Java反射特性--获取其他类实例并调用其方法

    1. 代码结构 .├── com│   └── test│   └── MyTest.java└── MainCall.java 2. 代码内容 MyTest.java: package com.te ...

  4. 类实例调用静态方法(Java)

    前言 第一次看到在Java中是可以通过类实例调用静态方法,当然不推荐这么做,接下来会讲到,但是在C#中通过类实例调用静态方法在编译时就不会通过,这里做下记录. 类实例调用静态方法 首先我们来看一个简单 ...

  5. 浅谈一致性哈希(My转)

    一致性哈希(Consistent hashing)算法是由 MIT 的Karger 等人与1997年在一篇学术论文(<Consistent hashing and random trees: d ...

  6. Dubbo一致性哈希负载均衡的源码和Bug,了解一下?

    本文是对于Dubbo负载均衡策略之一的一致性哈希负载均衡的详细分析.对源码逐行解读.根据实际运行结果,配以丰富的图片,可能是东半球讲一致性哈希算法在Dubbo中的实现最详细的文章了. 文中所示源码,没 ...

  7. Java_一致性哈希算法与Java实现

    摘自:http://blog.csdn.net/wuhuan_wp/article/details/7010071 一致性哈希算法是分布式系统中常用的算法.比如,一个分布式的存储系统,要将数据存储到具 ...

  8. 一致性哈希算法学习及JAVA代码实现分析

    1,对于待存储的海量数据,如何将它们分配到各个机器中去?---数据分片与路由 当数据量很大时,通过改善单机硬件资源的纵向扩充方式来存储数据变得越来越不适用,而通过增加机器数目来获得水平横向扩展的方式则 ...

  9. 一致性哈希算法原理及Java实现

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

随机推荐

  1. struts项目中添加的jar包

    一般我们使用struts时,添加的jar如下: commons-fileupload-1.2.1.jar commons-io-1.3.2.jar freemarker-2.3.16.jar java ...

  2. Django模板-在视图中使用模板

    之前我们已经有了自己的视图mysite.views.py中,应该是这样子的 from django.http import HttpResponse import datetime def curre ...

  3. opencv如何截取子图像

     首先用GetSubRect函数确定子图像的区域 GetSubRect 返回输入的图像或矩阵的矩形数组子集的矩阵头 CvMat* cvGetSubRect( const CvArr* arr, CvM ...

  4. js题

    function newStr(){ return "hi";}function turn(str){ str.toString = newStr;}var str1 = &quo ...

  5. 取PE文件的引入表和导出表

    直接上代码(这里列出C++和Delphi的代码),Delphi代码中包含导入及导出文件和函数列表,PE结构可参阅资料,很多很详细,需要注意的是,本例中是映射到内存,不是通过PE装载器装入的,所以对于节 ...

  6. C++流操作之fstream

    在Windows平台对文件进行存取操作可选的方案有很多,如果采用纯C,则需要用到File*等,当然也可以直接调用Windows API来做:如果采用C++,首先想到的就是文件流fstream.虽然在C ...

  7. poj3077---进位

    #include <stdio.h> #include <stdlib.h> #include<string.h> ]; ]; int main() { int n ...

  8. Hoeffding连接到机器学习

    统计学场景: 一个罐子中有红球和绿球,红球比例$v$未知,数量未知,如何得到红球比例?方法---随机抽样N个球,在其中红球占比为$u$ 由hoeffding可以知道:$P(|u-v|>\epsi ...

  9. Backward Digit Sums(暴力)

    Backward Digit Sums Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5664   Accepted: 32 ...

  10. 面试题25:最小的K个数

    方法一:对n个整数进行排序(快速排序或堆排序),取出前K个元素(最容易想到的最笨的方法,不可取) 时间复杂度:O(n*logn) + O(k) = O(n*logn) 采用快速排序的代码: #incl ...