分布式一致性hash算法
写在前面
在学习Redis的集群内容时,看到这么一句话:Redis并没有使用一致性hash算法,而是引入哈希槽的概念。而分布式缓存Memcached则是使用分布式一致性hash算法来实现分布式存储。所以就专门学习了一下
什么是分布式?什么是一致性?什么是哈希?
1)分布式(distributed)是指在多台不同的服务器中部署不同的服务模块,通过远程调用协同工作,对外提供服务。“分布式一致性hash算法”中的“分布式”就是指缓存数据的分布性。
集中式将一个系统的所有服务模块部署到了不同的服务器上,构成一个集群,通过负载均衡设备对外提供服务。集中式部署就像茶水间同时有多个饮水机提供服务,服务冗余部署。分布式部署则将系统拆分成不同的服务模块,然后将不同的服务模块部署在不同的服务器上。
2)一致性Wiki的定义:
Consistent hashing is a special kind of hashing such that when a hash table is resized, only K/n keys need to be remapped on average, where K is the number of keys, and n is the number of slots. In contrast, in most traditional hash tables, a change in the number of array slots causes nearly all keys to be remapped because the mapping between the keys and the slots is defined by a modular operation.
大概意思就是“一致性哈希是一种特殊的哈希算法,提供了这样的一个哈希表,当重新调整大小的时候,平均只有部分(k/n)key需要重新映射哈希槽,而不像传统哈希表那样几乎所有key需要需要重新映射哈希槽”。一致性hash能保证在分布式环境中,对key进行哈希的结果或者说key与节点之间的映射关系不会受节点的增加和删除而产生重大的变化。
3)hash,俗称“哈希”,也叫散列,是一种将任意长度的消息(数据)压缩到某一固定长度的消息摘要(数据)的算法。常见的hash算法有MD5,SHA等。hash算法具有几个重要的特性:不可逆性(即从hash值反推出原消息是不可能的)、抗冲突性(即给定消息M1,不存在另一个消息M2,使得Hash(M1)=Hash(M2))和分布均匀性(即hash的结果是均匀分布的)。Memcached中,存取数据时都要进行哈希映射。正是这几个特性,保证了memcached缓存中key值得唯一性。
分布式一致性hash算法使用背景
我们已经知道,memcached的分布式主要在于客户端的分布式算法。memcached客户端就像一个网络中的路由,经过特定的算法将数据分散的存在到memcached服务端的机器上,又从分散的memcached服务端的机器上提取数据。实际中,常见的存储和提取数据的算法有取模算法和本文分析的一致性hash算法。
取模算法算法的原理是:
hash(key)%N
1
其中key 代表数据的键,N 代表memcached服务器的数量。取模的结果就是memcached客户端要定位的memcached服务器。取模算法很明显,结果受N的影响,当服务器数量N增加或者减少的时候,原先的缓存数据定位几乎失效,缓存数据定位失效意味着要到数据库重新查询,这对于高并发的系统来说是致命的。于是,人们提出了一致性hash算法,最终目的是实现在移除、添加一个memcached服务器时对已经存在的缓存数据的定位影响尽可能的降到最小。
环形hash空间
通常,一个缓存数据的key经过hash后会得到一个32位的值,也就是0~2^32 - 1数值范围。我们可以把这个数值范围抽象成一个首尾相连环形的空间,我们称这个空间为环形hash空间。如下图所示:
映射key、server节点到环形hash空间
有了环形hash空间之后,缓存数据的key经过hash后得到的值就映射到了环形hash空间。假设有key1、key2、key3、key4,经过hash后,映射到环形hash空间如下图所示。同理,我们可以把memcached服务器抽象成网络上的节点经过hash后映射到环形hash空间。假设有server1(可以是服务器的某些唯一标志信息,如ip等)、server2、server3
映射key到server节点
现在缓存key和server节点都经过一致性hash算法映射到了环形hash空间,现在就可以将缓存key和server节点的关系进行映射了。顺时针沿着环形hash空间,从某个缓存key开始,直到遇到一个server节点,那么该缓存key就存储到这个server节点上。如图:
了解了key、server节点、hash空间之间的映射关系之后,已经清楚了缓存数据是怎样分布的存储到memcached服务器了。查找缓存数据的时候,也采用同样的映射方法来定位。
删除server节点
当在server集群中删除server2节点时,受影响的也仅是server1~server2之间的缓存数据Key3,这部分数据需要重新到数据库查找再次映射到server3节点上。如下图所示:
添加server节点
现在我们已经知道memcached存储和访问数据的策略了。那么当在server集群中增加一个server节点时,对数据访问的命中率又有什么影响呢。如下图,在server1和server2节点之间增加一个节点server4
从上图可以看出,增加server4节点后,原有的缓存数据分布中,仅有server1和server4节点之间的数据进行了重新分布,这部分数据需要重新到数据库查找再次映射到新添加的server4节点上。尽管不能命中的缓存数据仍然存在,但相对于取模算法,已经是最大限度地抑制了hash键的重新分布。
虚拟节点的引入
我们已经知道,添加和删除节点都会影响缓存数据的分布。尽管hash算法具有分布均匀的特性,但是当集群中server数量很少时,他们可能在环中的分布并不是特别均匀,进而导致缓存数据不能均匀分布到所有的server上。
为解决这个问题,需要使用虚拟节点的思想:为每个物理节点(server)在环上分配100~200个点,这样环上的节点较多,就能抑制分布不均匀。当为cache定位目标server时,如果定位到虚拟节点上,就表示cache真正的存储位置是在该虚拟节点代表的实际物理server上。另外,如果每个实际server节点的负载能力不同,可以赋予不同的权重,根据权重分配不同数量的虚拟节点。
虚拟节点的hash计算可以采用对应节点的 IP 地址加数字后缀的方式。例如假设 serverA 的 IP 地址为 127.0.0.1 。
引入虚拟节点前,计算serverA 的 hash 值:
hash(“127.0.0.1”);
1
引入虚拟节点后,计算虚拟节点serverA1 和 serverA2 的 hash 值:
hash(“127.0.0.1#1”);
hash(“127.0.0.1#2”);
1
2
一致性hash算法与取模算法的比较
取模算法的方法简单,数据的分散性也可以,但其主要缺点是当添加或移除server节点时,缓存重新映射的代价相当巨大。添加或移除server节点时,余数就会产生巨变,这样就无法定位与存储时相同的server节点,从而影响缓存的命中率。
而一致性hash算法则最大限度的减少了server节点变化带来的影响,当节点变化时,只影响一个server节点的部分数据,且hash算法能够保证需要重新分布的缓存数据能映射到新的server节点中。
---------------------
原文:https://blog.csdn.net/u011489043/article/details/78944985
分布式一致性hash算法的更多相关文章
- memcache分布式 [一致性hash算法] 的php实现
最近在看一些分布式方面的文章,所以就用php实现一致性hash来练练手,以前一般用的是最原始的hash取模做分布式,当生产过程中添加或删除一台memcache都会造成数据的全部失效,一致性hash就是 ...
- 分布式缓存技术memcached学习(四)—— 一致性hash算法原理
分布式一致性hash算法简介 当你看到“分布式一致性hash算法”这个词时,第一时间可能会问,什么是分布式,什么是一致性,hash又是什么.在分析分布式一致性hash算法原理之前,我们先来了解一下这几 ...
- 分布式缓存技术memcached学习系列(四)—— 一致性hash算法原理
分布式一致性hash算法简介 当你看到"分布式一致性hash算法"这个词时,第一时间可能会问,什么是分布式,什么是一致性,hash又是什么.在分析分布式一致性hash算法原理之前, ...
- 一致性Hash算法在Redis分布式中的使用
由于redis是单点,但是项目中不可避免的会使用多台Redis缓存服务器,那么怎么把缓存的Key均匀的映射到多台Redis服务器上,且随着缓存服务器的增加或减少时做到最小化的减少缓存Key的命中率呢? ...
- 分布式缓存一致性hash算法理解
今天阅读了一下大型网络技术架构这本苏中的分布式缓存一致性hash算法这一节,针对大型分布式系统来说,缓存在该系统中必不可少,分布式集群环境中,会出现添加缓存节点的需求,这样需要保障缓存服务器中对缓存的 ...
- Nginx+Memcache+一致性hash算法 实现页面分布式缓存(转)
网站响应速度优化包括集群架构中很多方面的瓶颈因素,这里所说的将页面静态化.实现分布式高速缓存就是其中的一个很好的解决方案... 1)先来看看Nginx负载均衡 Nginx负载均衡依赖自带的 ngx_h ...
- 分布式缓存设计:一致性Hash算法
缓存作为数据库前的一道屏障,它的可用性与缓存命中率都会直接影响到数据库,所以除了配置主从保证高可用之外还需要设计分布式缓存来扩充缓存的容量,将数据分布在多台机器上如果有一台不可用了对整体影响也比较小. ...
- 分布式缓存一致性hash算法
当服务器不多,并且不考虑扩容的时候,可直接使用简单的路由算法,用服务器数除缓存数据KEY的hash值,余数作为服务器下标即可. 但是当业务发展,网站缓存服务需要扩容时就会出现问题,比如3台缓存服务器要 ...
- 7.redis 集群模式的工作原理能说一下么?在集群模式下,redis 的 key 是如何寻址的?分布式寻址都有哪些算法?了解一致性 hash 算法吗?
作者:中华石杉 面试题 redis 集群模式的工作原理能说一下么?在集群模式下,redis 的 key 是如何寻址的?分布式寻址都有哪些算法?了解一致性 hash 算法吗? 面试官心理分析 在前几年, ...
随机推荐
- 【BZOJ3379】[Usaco2004 Open]Turning in Homework 交作业
题解: 比较容易想到二分答案+时间逆流 这样就变成了经典的路灯问题 f[a][b][0/1] 其实可以不用二分答案 根据倒着考虑我们会发现一定是先走旁边的再走中间的 计算到当前点+下课时间所需的最小时 ...
- 【BZOJ1778】[Usaco2010 Hol]Dotp 驱逐猪猡
题解: 网上有一种复杂的方法..好像复杂度并没有优势就没看 定义f[i]表示i的期望经过次数,f[i]=sigma{f[j]*p/q/du[j]}+(i==1); 然后高斯消元就可以了 最后求出来的f ...
- Crystal Reports报表使用 [一]
1.Crystal Reports 是什么? Crystal Reports 是一个功能强大.动态和可操作的报表解决方案,它将帮助你通过网络设计.开发.可视化及发布报表,或嵌入到企业应用之中.有了它, ...
- Android动画模式
在Android中,有两种动画模式:Tween Animation(渐变动画)和Frame Animation(帧动画).渐变动画是通过对场景里的对象不断做图像变换(平移.缩放.旋转等)来产生动画效果 ...
- 系统环境变量(就是不需要切换目录,敲击“python”就可以进入编码器)
1.右击我的电脑,选择属性,选择“高级系统设置” 2.选择高级,选择环境变量 3.在系统变量中找到path,点击编辑.然后新建,将python的路径复制进去,点击确定.
- 【LeetCode算法-14】Longest Common Prefix
Write a function to find the longest common prefix string amongst an array of strings. If there is n ...
- Apache系列:Apache的全局配置
配置文件组成: 整个配置文件由3段组成: (1)全局配置:对主服务器或虚拟机都有效,且有些功能是服务器自身工作属性: (2)主服务器:主站属性: (3)虚拟主机:虚拟主机及属性定义 注:第二段和第三段 ...
- jenkins+springboot+svn linux 自动化部署
需要下载 publish over ssh 插件(远程上传项目到服务器) Maven Integration plugin 插件(构建maven项目) 然后将各种配置配置好 最终项目在服务器上的路径是 ...
- SpringMVC(十四) RequestMapping ModelAndView
ModelAndView返回模型数据和视图.参考以下Demo代码,了解其实现方法.关注通过视图名称创建ModelAndView的构造方法,以及通过${requestScope.attribute}的方 ...
- Altium Desgner软件,PCB设计中铺铜的作用
PS原文出自http://mp.weixin.qq.com/s/5mLNXzCDm1hGOXiKNE8Ddg 问1:为何要铺铜? 答:一般铺铜有几个方面原因. 1.EMC.对于大面积的地或电源铺铜,会 ...