值得注意的点

  1. 哈希函数的选择
  • murmur哈希函数

    该函数是非加密型哈希,性能高,且发生哈希碰撞的概率据说很低
  • md5
  • SHA
  • 可以选择guava包,提供了丰富的哈希函数的API
  1. 支持虚拟节点+加权,因为不同的节点可能资源配置不同,加权可以使负载均衡最大化,虚拟节点,可以降低某个节点出现问题后对整个哈希环的冲击

  2. 考虑到不同场景用来作哈希的key可能不一样,所以提供一个包装类Node,可以自定义key,且可以自定义权重

  3. 安全问题,添加节点和删除节点是需要重建哈希环,此处要考虑并发情况的发生(此处暂未实现),一般情况下只需初始化一次即可。

  4. 哈希后的取值,本处为了通用采用String类型,可以针对特殊场景作优化,个人认为只有最适合的,没有最好的

实现

  1. 包装类node
public final class Node<T> {

    public static final int DEFAULT_WEIGHT = 1;

    private T target;
private String key;
private int weight = DEFAULT_WEIGHT; public Node(T target) {
this.target = target;
this.key = target.toString();
} public Node(T target, String key) {
this.target = target;
this.key = key;
} public Node(T target, String key, int weight) {
this.target = target;
this.key = key;
this.weight = weight;
} public T getTarget() {
return target;
} public void setTarget(T target) {
this.target = target;
} public String getKey() {
return key;
} public void setKey(String key) {
this.key = key;
} public int getWeight() {
return weight;
} public void setWeight(int weight) {
this.weight = weight;
}
}
  1. 一致性哈希
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing; import java.nio.charset.Charset;
import java.util.*; /**
* 一致性哈希
* @param <T>
*/
public class ConsistentHash<T> { //哈希函数
private HashFunction hashFunction = Hashing.murmur3_32();
//哈希环
private TreeMap<String, Node<T>> nodeMappings = new TreeMap<>();
//虚拟节点数
private int replicas = 160;
//真实节点
private List<Node<T>> realNodes; public ConsistentHash(HashFunction hashFunction, List<Node<T>> realNodes, int replicas) {
this.hashFunction = hashFunction;
this.realNodes = realNodes;
this.replicas = replicas;
} public ConsistentHash(HashFunction hashFunction, List<Node<T>> realNodes) {
this.hashFunction = hashFunction;
this.realNodes = realNodes;
} public ConsistentHash(List<Node<T>> realNodes, int replicas) {
this.realNodes = realNodes;
this.replicas = replicas;
} public ConsistentHash(List<Node<T>> realNodes) {
this.realNodes = realNodes;
} /**
* 初始化哈希环
*/
public void init(){
realNodes.forEach(node -> {
for (int i = 0; i < replicas*node.getWeight(); i++) {
StringBuilder sb = new StringBuilder(node.getKey());
sb.append(i);
nodeMappings.put(hashCode(sb.toString()), node);
}
});
} public String hashCode(String key){
return hashFunction.hashString(key, Charset.defaultCharset()).asBytes().toString();
} public Node<T> getNode(String key){
SortedMap<String, Node<T>> tailMap = nodeMappings.tailMap(hashCode(key));
if(tailMap.isEmpty()){
return nodeMappings.get(nodeMappings.firstKey());
}
return tailMap.get(tailMap.firstKey());
} public static void main(String[] args) {
List<Node<String>> realNodes = Arrays.asList(new Node("127.0.0.1"),new Node("192.168.4.175"),new Node("192.168.3.175"), new Node("172.147.0.101"));
ConsistentHash consistentHash = new ConsistentHash(Hashing.md5(), realNodes);
consistentHash.init(); List<Node> one = new ArrayList<>();
List<Node> two = new ArrayList<>();
List<Node> three = new ArrayList<>();
List<Node> four = new ArrayList<>();
for (int i = 0; i <10000 ; i++) {
Node<String> node = consistentHash.getNode("node"+i);
if(node.getKey().equals("127.0.0.1")){
one.add(node);
}
if(node.getKey().equals("192.168.4.175")){
two.add(node);
}
if(node.getKey().equals("192.168.3.175")){
three.add(node);
}
if(node.getKey().equals("172.147.0.101")){
four.add(node);
}
}
System.out.println(one.size());
System.out.println(two.size());
System.out.println(three.size());
System.out.println(four.size());
}

一致性哈希java实现的更多相关文章

  1. 一致性哈希Java源码分析

    首次接触一致性哈希是在学习memcached的时候,为了解决分布式服务器的负载均衡或者说选路的问题,一致性哈希算法不仅能够使memcached服务器被选中的概率(数据分布)更加均匀,而且使得服务器的增 ...

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

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

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

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

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

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

  5. 一致性哈希与java实现

    一致性哈希算法是分布式系统中常用的算法.比如,一个分布式的存储系统,要将数据存储到具体的节点上,如果采用普通的hash方法,将数据映射到具体的节点上,如key%N,key是数据的key,N是机器节点数 ...

  6. 一致性哈希算法原理、避免数据热点方法及Java实现

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

  7. 负载均衡-基础-一致性哈希算法及java实现

    一致性hash算法,参考: http://www.blogjava.net/hello-yun/archive/2012/10/10/389289.html 针对这篇文章,加入了自己的理解,在原有的代 ...

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

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

  9. [转载] 应用于负载均衡的一致性哈希及java实现

    转载自http://blog.csdn.net/haitao111313/article/details/7537799 这几天看了几遍一致性哈希的文章,但是都没有比较完整的实现,因此试着实现了一下, ...

随机推荐

  1. JMeter 插件管理

    JMeter管理的插件包括了jmeter-plugins.org上常用的插件以及各种第三方插件和JMeter核心插件. JMeter插件管理器主要管理插件安装,卸载,升级等操作. 安装插件管理 1.下 ...

  2. iOS使用带字体图标的UIButton(支持各种方向)

    简书地址:http://www.jianshu.com/p/1c288440754d demo地址:https://github.com/Brances/ZMProject

  3. JQ 为未来元素添加事件处理器—事件委托

    随着DOM结构的复杂化和Ajax等动态脚本技术的运用,有了较多的动态添加进来的元素,直接用JQ添加click事件会发现新添加进来的元素并不能直接选取到,在这里就需要用到事件委托方法,JQ为事件委托提供 ...

  4. 表单Checkbox全选反选全不选

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. php中const与define的区别

    1 版本差异: const 要求php的版本>5.3.0 define 可以兼容php4,php5 等版本 2 定义的位置区别: const关键字定义的常量是在编译时定义的,因此const关键字 ...

  6. Sticky Footer 绝对底部的两种套路

    最近面了好几个前端,工作经验有高有低,居然都不知道绝对底部是什么,也没有人能说出一种实现方式,让我不禁感慨前端领域的良莠不齐 绝对底部,或者说 Sticky Footer,是一种古老且经典的页面效果: ...

  7. scrapy使用PhantomJS爬取数据

    环境:python2.7+scrapy+selenium+PhantomJS 内容:测试scrapy+PhantomJS 爬去内容:涉及到js加载更多的页面 原理:配置文件打开中间件+修改proces ...

  8. jQuery DOM 元素方法 (十)

    函数 描述 .get() 获得由选择器指定的 DOM 元素. .index() 返回指定元素相对于其他指定元素的 index 位置. .size() 返回被 jQuery 选择器匹配的元素的数量. . ...

  9. 极光配置-》thinkphp3.2.3

    1,小白我搞了几天,终于得到了这样的结果(我猜应该是成功了吧). { "body": { "sendno": "100000", " ...

  10. golang其实也可以优先调度

    线上一个服务有个严重问题,处理消息数1k/s提升不上去,经过查看是阻塞在了一个新加的函数上,这个函数负责收集信息,送到一个channel上,再由某个函数处理,这个处理函数很简单,看不出任何问题,最大的 ...