强一致性hash实现java版本及强一致性hash原理
一致性 hash
分布式过程中我们将服务分散到若干的节点上,以此通过集体的力量提升服务的目的。然而,对于一个客户端来说,该由哪个节点服务呢?或者说对某个节点来说他分配到哪些任务呢?
强哈希
考虑到单服务器不能承载,因此使用了分布式架构,最初的算法为 hash() mod n, hash()通常取用户ID,n为节点数。此方法容易实现且能够满足运营要求。缺点是当单点发生故障时,系统无法自动恢复。同样不也不能进行动态增加节点。
弱哈希
为了解决单点故障,使用 hash() mod (n/m)
,
这样任意一个用户都有 m 个服务器备选,可由 client 随机选取。
由于不同服务器之间的用户需要彼此交互,所以所有的服务器需要确切的知道用户所在的位置。
因此用户位置被保存到 memcached 中。当一台发生故障,client 可以自动切换到对应 backup,由于切换前另外 1 台没有用户的 session,因此需要 client 自行重新登录。
- 好处
他比强哈希的好处是:解决了单点问题。
- 缺点
但存在以下问题:负载不均衡,尤其是单台发生故障后剩下一台会压力过大;不能动态增删节点;节点发生故障时需要 client 重新登录
一致性 hash 算法
一致性 hash 算法提出了在动态变化的 Cache 环境中,判定哈希算法好坏的四个定义:
平衡性(Balance)
平衡性是指哈希的结果能够尽可能分布到所有的缓冲中去,这样可以使得所有的缓冲空间都得到利用。很多哈希算法都能够满足这一条件。
单调性(Monotonicity)
单调性是指如果已经有一些内容通过哈希分派到了相应的缓冲中,又有新的缓冲加入到系统中。哈希的结果应能够保证原有已分配的内容可以被映射到原有的或者新的缓冲中去,而不会被映射到旧的缓冲集合中的其他缓冲区。
分散性(Spread)
在分布式环境中,终端有可能看不到所有的缓冲,而是只能看到其中的一部分。
当终端希望通过哈希过程将内容映射到缓冲上时,由于不同终端所见的缓冲范围有可能不同,从而导致哈希的结果不一致,最终的结果是相同的内容被不同的终端映射到不同的缓冲区中。
这种情况显然是应该避免的,因为它导致相同内容被存储到不同缓冲中去,降低了系统存储的效率。分散性的定义就是上述情况发生的严重程度。好的哈希算法应能够尽量避免不一致的情况发生,也就是尽量降低分散性。
负载(Load)
负载问题实际上是从另一个角度看待分散性问题。既然不同的终端可能将相同的内容映射到不同的缓冲区中,那么对于一个特定的缓冲区而言,也可能被不同的用户映射为不同的内容。
与分散性一样,这种情况也是应当避免的,因此好的哈希算法应能够尽量降低缓冲的负荷。
普通的哈希算法(也称硬哈希)采用简单取模的方式,将机器进行散列,这在cache环境不变的情况下能取得让人满意的结果,但是当cache环境动态变化时,
这种静态取模的方式显然就不满足单调性的要求(当增加或减少一台机子时,几乎所有的存储内容都要被重新散列到别的缓冲区中)。
代码实现
实现逻辑
一致性哈希算法有多种具体的实现,包括 Chord 算法,KAD 算法等实现,以上的算法的实现都比较复杂。
这里介绍一种网上广为流传的一致性哈希算法的基本实现原理,感兴趣的同学可以根据上面的链接或者去网上查询更详细的资料。
一致性哈希算法的基本实现原理是将机器节点和key值都按照一样的hash算法映射到一个0~2^32
的圆环上。
当有一个写入缓存的请求到来时,计算 Key 值 k 对应的哈希值 Hash(k),如果该值正好对应之前某个机器节点的 Hash 值,则直接写入该机器节点,
如果没有对应的机器节点,则顺时针查找下一个节点,进行写入,如果超过 2^32
还没找到对应节点,则从0开始查找(因为是环状结构)。
如图 1 所示:
图 1 中 Key K 的哈希值在 A 与 B 之间,于是 K 就由节点B来处理。
另外具体机器映射时,还可以根据处理能力不同,将一个实体节点映射到多个虚拟节点。
经过一致性哈希算法散列之后,当有新的机器加入时,将只影响一台机器的存储情况,
例如新加入的节点H的散列在 B 与 C 之间,则原先由 C 处理的一些数据可能将移至 H 处理,
而其他所有节点的处理情况都将保持不变,因此表现出很好的单调性。
而如果删除一台机器,例如删除 C 节点,此时原来由 C 处理的数据将移至 D 节点,而其它节点的处理情况仍然不变。
而由于在机器节点散列和缓冲内容散列时都采用了同一种散列算法,因此也很好得降低了分散性和负载。
而通过引入虚拟节点的方式,也大大提高了平衡性。
实现代码
原文地址
强一致性hash实现java版本及强一致性hash原理的更多相关文章
- at java.util.concurrent.ConcurrentHashMap.hash(ConcurrentHashMap.java:333)
at java.util.concurrent.ConcurrentHashMap.hash(ConcurrentHashMap.java:333) 原因: null request
- Java 集合 散列表hash table
Java 集合 散列表hash table @author ixenos 摘要:hash table用链表数组实现.解决散列表的冲突:开放地址法 和 链地址法(冲突链表方式) hash table 是 ...
- 【转】Java计算文件的hash值
原文地址:http://blog.csdn.net/qq_25646191/article/details/78863110 如何知道一个文件是否改变了呢?当然是用比较文件hash值的方法,文件has ...
- Java中String的hash函数分析
转载自:http://blog.csdn.net/hengyunabc/article/details/7198533 JDK6的源码: [java] view plaincopy /** * Ret ...
- JAVA版本区块链钱包核心代码
Block.java package com.ppblock.blockchain.core; import java.io.Serializable; /** * 区块 * @author yang ...
- Java版本:识别Json字符串并分隔成Map集合
前言: 最近又看了点Java的知识,于是想着把CYQ.Data V5迁移到Java版本. 过程发现坑很多,理论上看大部分很相似,实践上代码写起来发现大部分都要重新思考方案. 遇到的C#转Java的一些 ...
- 你的程序支持复杂的时间调度嘛?如约而来的 java 版本
你的程序支持复杂的时间调度嘛? 这篇文章介绍了时间适配器的c#版本,是给客户端用的,服务器自然也要有一套对应的做法,java版本的 [年][月][日][星期][时间] [*][*][*][*][*] ...
- 崔用志-微信开发-java版本
崔用志-微信开发-java版本 今天看到一些关于微信开发的知识蛮好的博客,分享给大家,希望对大家有帮助. 微信开发准备(一)--Maven仓库管理新建WEB项目 微信开发准备(二)--springmv ...
- java版本区别
java版本区别 点我,点我,Eclipse几个版本号的区别(part1) 点我,点我,Eclipse几个版本号的区别(part2) 点我,点我,Eclipse几个版本号的区别(part3)
随机推荐
- HTML下标签之应用
<!doctype html><html lang="en"> <head> <meta charset="UTF-8" ...
- 20164322韩玉婷 -----Exp1 PC平台逆向破解
Exp1 PC平台逆向破解 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件.该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串.该程序同时包含另一 ...
- Build up java environment(配置java环境)
1,配置环境变量 我的电脑,右键计算机图标,点击“属性” 点击“高级系统设置” 点击“环境变量” “系统变量”一栏,点击“新建” 弹出输入“变量名”.“变量值”窗口 “变量名”输入“JAVA_HOME ...
- [Java Web学习]Tomcat启动时报war exploded: Error during artifact deployment
报错:Artifact FirstWeb:war exploded: Error during artifact deployment. See server log for details. SEV ...
- 关于E-R图
E-R图 简介: E-R图也称实体-联系图(Entity Relationship Diagram),提供了表示实体类型.属性和联系的方法.用来描述现实世界的概念模型.它是描述现实世界概念结构模型的有 ...
- centos7通过yum安装mysql8
1.检查是否安装mariadb rpm -qa | grep mariadb 若有会显示 mariadb-libs-5.5.56-2.el7.x86_64 2.卸载mariadb rpm -e --n ...
- CF285D.Permutation Sum
想了很久觉得自己做法肯定T啊,就算是CF机子的3s时限,但我毕竟是 O ( C(15,7)*7!*log ) .... 果然在n=15的点T了...贱兮兮地特判了15过掉了,结果发现题解说就是打表.. ...
- Ubuntu中,wxpython的TextCtrl引发的error:_pixman_log_error
1>在windows下,执行下面的代码,不会报错,但是在Ubuntu下,就会报错 2>在Ubuntu下执行上面的代码,会提示下面的错. 解决方法: 若是TextCtrl中不写wx.TE_M ...
- 台式机安装Linux操作系统无法识别网卡
在公司一台台式机上安装centos7系统,发现安装好之后,发现没有自动生成eth0网卡. 查看网卡相关信息: lspci|grep Eth 获取到网卡型号后,可以去官网下载对应的安装包进行编译安装即可 ...
- The Oregon Trail 俄勒冈之旅
发售年份 1971 平台 多平台 开发商 MECC 类型 教育娱乐 https://www.youtube.com/watch?v=QBOLN7I8omY