值得注意的点

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

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

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

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

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

实现

  1. 包装类node
  1. public final class Node<T> {
  2. public static final int DEFAULT_WEIGHT = 1;
  3. private T target;
  4. private String key;
  5. private int weight = DEFAULT_WEIGHT;
  6. public Node(T target) {
  7. this.target = target;
  8. this.key = target.toString();
  9. }
  10. public Node(T target, String key) {
  11. this.target = target;
  12. this.key = key;
  13. }
  14. public Node(T target, String key, int weight) {
  15. this.target = target;
  16. this.key = key;
  17. this.weight = weight;
  18. }
  19. public T getTarget() {
  20. return target;
  21. }
  22. public void setTarget(T target) {
  23. this.target = target;
  24. }
  25. public String getKey() {
  26. return key;
  27. }
  28. public void setKey(String key) {
  29. this.key = key;
  30. }
  31. public int getWeight() {
  32. return weight;
  33. }
  34. public void setWeight(int weight) {
  35. this.weight = weight;
  36. }
  37. }
  1. 一致性哈希
  1. import com.google.common.hash.HashFunction;
  2. import com.google.common.hash.Hashing;
  3. import java.nio.charset.Charset;
  4. import java.util.*;
  5. /**
  6. * 一致性哈希
  7. * @param <T>
  8. */
  9. public class ConsistentHash<T> {
  10. //哈希函数
  11. private HashFunction hashFunction = Hashing.murmur3_32();
  12. //哈希环
  13. private TreeMap<String, Node<T>> nodeMappings = new TreeMap<>();
  14. //虚拟节点数
  15. private int replicas = 160;
  16. //真实节点
  17. private List<Node<T>> realNodes;
  18. public ConsistentHash(HashFunction hashFunction, List<Node<T>> realNodes, int replicas) {
  19. this.hashFunction = hashFunction;
  20. this.realNodes = realNodes;
  21. this.replicas = replicas;
  22. }
  23. public ConsistentHash(HashFunction hashFunction, List<Node<T>> realNodes) {
  24. this.hashFunction = hashFunction;
  25. this.realNodes = realNodes;
  26. }
  27. public ConsistentHash(List<Node<T>> realNodes, int replicas) {
  28. this.realNodes = realNodes;
  29. this.replicas = replicas;
  30. }
  31. public ConsistentHash(List<Node<T>> realNodes) {
  32. this.realNodes = realNodes;
  33. }
  34. /**
  35. * 初始化哈希环
  36. */
  37. public void init(){
  38. realNodes.forEach(node -> {
  39. for (int i = 0; i < replicas*node.getWeight(); i++) {
  40. StringBuilder sb = new StringBuilder(node.getKey());
  41. sb.append(i);
  42. nodeMappings.put(hashCode(sb.toString()), node);
  43. }
  44. });
  45. }
  46. public String hashCode(String key){
  47. return hashFunction.hashString(key, Charset.defaultCharset()).asBytes().toString();
  48. }
  49. public Node<T> getNode(String key){
  50. SortedMap<String, Node<T>> tailMap = nodeMappings.tailMap(hashCode(key));
  51. if(tailMap.isEmpty()){
  52. return nodeMappings.get(nodeMappings.firstKey());
  53. }
  54. return tailMap.get(tailMap.firstKey());
  55. }
  56. public static void main(String[] args) {
  57. 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"));
  58. ConsistentHash consistentHash = new ConsistentHash(Hashing.md5(), realNodes);
  59. consistentHash.init();
  60. List<Node> one = new ArrayList<>();
  61. List<Node> two = new ArrayList<>();
  62. List<Node> three = new ArrayList<>();
  63. List<Node> four = new ArrayList<>();
  64. for (int i = 0; i <10000 ; i++) {
  65. Node<String> node = consistentHash.getNode("node"+i);
  66. if(node.getKey().equals("127.0.0.1")){
  67. one.add(node);
  68. }
  69. if(node.getKey().equals("192.168.4.175")){
  70. two.add(node);
  71. }
  72. if(node.getKey().equals("192.168.3.175")){
  73. three.add(node);
  74. }
  75. if(node.getKey().equals("172.147.0.101")){
  76. four.add(node);
  77. }
  78. }
  79. System.out.println(one.size());
  80. System.out.println(two.size());
  81. System.out.println(three.size());
  82. System.out.println(four.size());
  83. }

一致性哈希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. volatile作用及相关集合类

    在工作一年多之后,java程序员都会了解到volatile 这个修饰符, 其在多线程环境下解决了long/double写操作的原子性.基本变量的可见性.通过建立内存屏障保证指令有序性 那么在哪些Jav ...

  2. Python函数篇(7)-正则表达式

    1.正则表达式   正则表达式为高级的文本模式匹配,抽取,与/或文本形式的搜索和替换功能提供了基础,简单的来说,正则表达式是由一些字符和特殊符号组成的字符串.Python通过标准库中的re模块来支持正 ...

  3. js数组操作-添加,删除

    js 数组操作常用方法. push():在数组后面加入元素,并返回数组的长度 unshift():在数组前面加入元素,并返回数组的长度 pop()删除最后一个元素 shift()删除第一个元素 var ...

  4. shell日志删除(超容量&自动)

    背景:避免双十一磁盘被打爆,本想通过crontab执行,但是删除需要密码,所以用作当机器磁盘高于摸个阈值,进行无关性日志强删 #!/bin/sh #use #sh clean.sh wmporder_ ...

  5. 3、公司开会的必要性 - CEO之公司管理经验谈

    这几天在考虑开公司的问题.以前也有想过开公司创业,但是由于资金和团队问题搁置了.今天在网上看到了一篇文“[转]微软是这么管理员工的!你一定向往!”,想起以前在其它公司时开的一些会议的问题,就写了此文, ...

  6. centos虚拟机初始化脚本

    功能 修改主机名为node. 网卡开机启动并设置ip为静态18.8 更新yum源为国内yum源,并安装vim lrzsz wget man ntpdate软件. 关闭iptables selinux, ...

  7. web打印总结

    一.打印样式 区别显示和打印的样式 使用media="print"控制打印时的样式,如下: 打印时不显示打印按钮,设置页面宽度 <style media="prin ...

  8. js设置元素class方法小结及classList相关

        给DOM元素设置class是我们在项目中非常容易遇到的,网上的资料和总结也比较多,下面比较全面的整理一下,希望给到大家一些帮助!并引用两种成熟的classList的兼容方法 一.el.setA ...

  9. 通俗易懂的信息熵与信息增益(IE, Information Entropy; IG, Information Gain)

    信息熵与信息增益(IE, Information Entropy; IG, Information Gain) 信息增益是机器学习中特征选择的关键指标,而学习信息增益前,需要先了解信息熵和条件熵这两个 ...

  10. File System 之本地文件系统

    上一篇文章提到了,最近做一个基于 File System/IndexedDB的应用,上一篇是定额和使用的查询. 因为LocalFileSystem只有chrome支持,有点尴尬,如果按需加载又何来尴尬 ...