一致性哈希算法是分布式系统中常用的算法。比如,一个分布式的存储系统,要将数据存储到具体的节点上,如果采用普通的hash方法,将数据映射到具体的节点上,如key%N,key是数据的key,N是机器节点数,如果有一个机器加入或退出这个集群,则所有的数据映射都无效了,如果是持久化存储则要做数据迁移,如果是分布式缓存,则其他缓存就失效了。

因此,引入了一致性哈希算法:

把数据用hash函数(如MD5),映射到一个很大的空间里,如图所示。数据的存储时,先得到一个hash值,对应到这个环中的每个位置,如k1对应到了图中所示的位置,然后沿顺时针找到一个机器节点B,将k1存储到B这个节点中。

如果B节点宕机了,则B上的数据就会落到C节点上,如下图所示:

这样,只会影响C节点,对其他的节点A,D的数据不会造成影响。然而,这又会造成一个“雪崩”的情况,即C节点由于承担了B节点的数据,所以C节点的负载会变高,C节点很容易也宕机,这样依次下去,这样造成整个集群都挂了。

为此,引入了“虚拟节点”的概念:即把想象在这个环上有很多“虚拟节点”,数据的存储是沿着环的顺时针方向找一个虚拟节点,每个虚拟节点都会关联到一个真实节点,如下图所使用:

图中的A1、A2、B1、B2、C1、C2、D1、D2都是虚拟节点,机器A负载存储A1、A2的数据,机器B负载存储B1、B2的数据,机器C负载存储C1、C2的数据。由于这些虚拟节点数量很多,均匀分布,因此不会造成“雪崩”现象。

public class Shard { // S类封装了机器节点的信息 ,如name、password、ip、port等

private TreeMap nodes; // 虚拟节点

private List shards; // 真实机器节点

private final int NODE_NUM = 100; // 每个机器节点关联的虚拟节点个数

public Shard(List shards) {

super();

this.shards = shards;

init();

}

private void init() { // 初始化一致性hash环

nodes = new TreeMap();

for (int i = 0; i != shards.size(); ++i) { // 每个真实机器节点都需要关联虚拟节点

final S shardInfo = shards.get(i);

for (int n = 0; n < NODE_NUM; n++)

// 一个真实机器节点关联NODE_NUM个虚拟节点

nodes.put(hash("SHARD-" + i + "-NODE-" + n), shardInfo);

}

}

public S getShardInfo(String key) {

SortedMap tail = nodes.tailMap(hash(key)); // 沿环的顺时针找到一个虚拟节点

if (tail.size() == 0) {

return nodes.get(nodes.firstKey());

}

return tail.get(tail.firstKey()); // 返回该虚拟节点对应的真实机器节点的信息

}

/**

* MurMurHash算法,是非加密HASH算法,性能很高,

* 比传统的CRC32,MD5,SHA-1(这两个算法都是加密HASH算法,复杂度本身就很高,带来的性能上的损害也不可避免)

* 等HASH算法要快很多,而且据说这个算法的碰撞率很低.

* http://murmurhash.googlepages.com/

*/

private Long hash(String key) {

ByteBuffer buf = ByteBuffer.wrap(key.getBytes());

int seed = 0x1234ABCD;

ByteOrder byteOrder = buf.order();

buf.order(ByteOrder.LITTLE_ENDIAN);

long m = 0xc6a4a7935bd1e995L;

int r = 47;

long h = seed ^ (buf.remaining() * m);

long k;

while (buf.remaining() >= 8) {

k = buf.getLong();

k *= m;

k ^= k >>> r;

k *= m;

h ^= k;

h *= m;

}

if (buf.remaining() > 0) {

ByteBuffer finish = ByteBuffer.allocate(8).order(

ByteOrder.LITTLE_ENDIAN);

// for big-endian version, do this first:

// finish.position(8-buf.remaining());

finish.put(buf).rewind();

h ^= finish.getLong();

h *= m;

}

h ^= h >>> r;

h *= m;

h ^= h >>> r;

buf.order(byteOrder);

return h;

}

}

其他资料

java murmurhash实现_一致性哈希算法与Java实现相关推荐

  1. 【重难点】【Java基础 01】一致性哈希算法、sleep() 和wait() 的区别、强软弱虚引用

    [重难点][Java基础 01]一致性哈希算法.sleep() 和wait() 的区别.强软弱虚引用 文章目录 [重难点][Java基础 01]一致性哈希算法.sleep() 和wait() 的区别. ...

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

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

  3. java 取绝对值_Java实现一致性哈希算法,并搭建环境测试其负载均衡特性

    实现负载均衡是后端领域一个重要的话题,一致性哈希算法是实现服务器负载均衡的方法之一,你很可能已在一些远程服务框架中使用过它.下面我们尝试一下自己实现一致性哈希算法. 一. 简述一致性哈希算法 这里不详 ...

  4. 先来先服务算法代码_一致性哈希算法编写

    今天我想先给大家科普下一致性哈希算法这块,因为我下一篇文章关于缓存的高可用需要用到这个,但是又不能直接在里面写太多的代码以及关于一致性hash原理的解读,这样会失去对于缓存高可用的理解而且会造成文章很 ...

  5. 哈希运算python实现_一致性哈希算法 python实现

    # -*- coding: utf-8 -*- """ 一致性哈希算法 python实现 参考 http://weblogs.java.net/blog/2007/11/ ...

  6. 一致性hash算法虚拟节点_一致性哈希算法——虚拟节点

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

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

    1 /** 2 * 一致性hash 的java 实现3 *@authorluoqiang4 * @data 2016/11/085 */ 6 public classConsistencyHash { ...

  8. java hashtable 数据结构_数据结构--哈希表(Java)

    数据结构--哈希表(Java) 介绍 哈希表 底层是 数组加链表 或者是 数组加二叉树 ,一个数组里面有多个链表,通过散列函数来提高效率 代码 package cn.guizimo.hashtab; ...

  9. java 查找排序_查找与排序算法(Java实现)

    1.二分查找算法 package other; public class BinarySearch { /* * 循环实现二分查找算法arr 已排好序的数组x 需要查找的数-1 无法查到数据 */ p ...

最新文章

  1. Memcache内存分配策略
  2. 软件常见故障的现象、故障排除的方法
  3. WinUI 3 试玩报告
  4. leetcode78. 子集(回溯)
  5. php 模板 php + mysql + myodbc,连接MySQL数据库在ASP中,就用MyODBC
  6. 王爽 汇编语言第三版 第11章 标志寄存器
  7. 不同vlan通信(三层交换)
  8. 微信小程序,引爆新热点!JEECG社区小程序实战培训,业内首发,实战干货!
  9. 即使在移动AI时代,软件仍将主导业界
  10. 安卓案例:初试谷歌图表
  11. scp命令报错-bash: scp: command not found
  12. Silverlight 国外技术文章
  13. Markdown(五)——绘图工具mermaid之流程图Flowchart
  14. JavaScript --------WebS APIs学习之网页特效(offset系列)
  15. 塔夫斯大学计算机教授,塔夫茨大学工程学院虚拟教室取得成功!
  16. 相机视场角和焦距_摄像机焦距和视场角计算.doc
  17. 新浪php工程师面试题
  18. 微信小程序页面回到顶端的方式
  19. 如何使用ECharts绘制甘特图
  20. 【Python 3 的基础语法】

热门文章

  1. Java的native方法返回数组return Array(C语言)
  2. Django:ORM基本操作-CRUD,管理器对象objects,----->聚合查询、原生数据库操作
  3. 懂得智能配色的ImageView,还能给自己设置多彩的阴影(PaletteImageView)
  4. K-means聚类分析算法(二)
  5. python的django框架http请求_python django框架(一)
  6. 51单片机的轮胎气压监测系统_汽车的胎压监测系统有哪些作用?
  7. ibm linux mq 发送消息_IBM MQ简明教程——2. 将消息发送至远程队列
  8. AI队列长度检测:使用YOLO进行图像中的对象检测
  9. .NET中的异步编程——常见的错误和最佳实践
  10. python自己写包_如何将自己的Python包发布到PyPI