Cynric 的博客
修身齐家治国平天下 格物致知诚意正己心
一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似。一致性哈希修正了CARP使用的简 单哈希算法带来的问题,使得分布式哈希(DHT)可以在P2P环境中真正得到应用。
一致性hash算法提出了在动态变化的Cache环境中,判定哈希算法好坏的四个定义:
1、平衡性(Balance):平衡性是指哈希的结果能够尽可能分布到所有的缓冲中去,这样可以使得所有的缓冲空间都得到利用。很多哈希算法都能够满足这一条件。
2、单调性(Monotonicity):单调性是指如果已经有一些内容通过哈希分派到了相应的缓冲中,又有新的缓冲加入到系统中。哈希的结果应能够保证原有已分配的内容可以被映射到原有的或者新的缓冲中去,而不会被映射到旧的缓冲集合中的其他缓冲区。
3、分散性(Spread):在分布式环境中,终端有可能看不到所有的缓冲,而是只能看到其中的一部分。当终端希望通过哈希过程将内容映射到缓冲上时,由于不同终端所见的缓冲范围有可能不同,从而导致哈希的结果不一致,最终的结果是相同的内容被不同的终端映射到不同的缓冲区中。这种情况显然是应该避免的,因为它导致相同内容被存储到不同缓冲中去,降低了系统存储的效率。分散性的定义就是上述情况发生的严重程度。好的哈希算法应能够尽量避免不一致的情况发生,也就是尽量降低分散性。
4、负载(Load):负载问题实际上是从另一个角度看待分散性问题。既然不同的终端可能将相同的内容映射到不同的缓冲区中,那么对于一个特定的缓冲区而言,也可能被不同的用户映射为不同 的内容。与分散性一样,这种情况也是应当避免的,因此好的哈希算法应能够尽量降低缓冲的负荷。
在分布式集群中,对机器的添加删除,或者机器故障后自动脱离集群这些操作是分布式集群管理最基本的功能。如果采用常用的hash(object)%N算法,那么在有机器添加或者删除后,很多原有的数据就无法找到了,这样严重的违反了单调性原则。接下来主要讲解一下一致性哈希算法是如何设计的:
环形Hash空间
按照常用的hash算法来将对应的key哈希到一个具有2^32次方个桶的空间中,即0~(2^32)-1的数字空间中。现在我们可以将这些数字头尾相连,想象成一个闭合的环形。如下图
把数据通过一定的hash算法处理后映射到环上
现在我们将object1、object2、object3、object4四个对象通过特定的Hash函数计算出对应的key值,然后散列到Hash环上。如下图:
Hash(object1) = key1;
Hash(object2) = key2;
Hash(object3) = key3;
Hash(object4) = key4;
将机器通过hash算法映射到环上
在采用一致性哈希算法的分布式集群中将新的机器加入,其原理是通过使用与对象存储一样的Hash算法将机器也映射到环中(一般情况下对机器的hash计算是采用机器的IP或者机器唯一的别名作为输入值),然后以顺时针的方向计算,将所有对象存储到离自己最近的机器中。
假设现在有NODE1,NODE2,NODE3三台机器,通过Hash算法得到对应的KEY值,映射到环中,其示意图如下:
Hash(NODE1) = KEY1;
Hash(NODE2) = KEY2;
Hash(NODE3) = KEY3;
通过上图可以看出对象与机器处于同一哈希空间中,这样按顺时针转动object1存储到了NODE1中,object3存储到了NODE2中,object2、object4存储到了NODE3中。在这样的部署环境中,hash环是不会变更的,因此,通过算出对象的hash值就能快速的定位到对应的机器中,这样就能找到对象真正的存储位置了。
机器的删除与添加
普通hash求余算法最为不妥的地方就是在有机器的添加或者删除之后会照成大量的对象存储位置失效,这样就大大的不满足单调性了。下面来分析一下一致性哈希算法是如何处理的。
1. 节点(机器)的删除
以上面的分布为例,如果NODE2出现故障被删除了,那么按照顺时针迁移的方法,object3将会被迁移到NODE3中,这样仅仅是object3的映射位置发生了变化,其它的对象没有任何的改动。如下图:
2. 节点(机器)的添加
如果往集群中添加一个新的节点NODE4,通过对应的哈希算法得到KEY4,并映射到环中,如下图:
通过按顺时针迁移的规则,那么object2被迁移到了NODE4中,其它对象还保持这原有的存储位置。通过对节点的添加和删除的分析,一致性哈希算法在保持了单调性的同时,还是数据的迁移达到了最小,这样的算法对分布式集群来说是非常合适的,避免了大量数据迁移,减小了服务器的的压力。
平衡性
根据上面的图解分析,一致性哈希算法满足了单调性和负载均衡的特性以及一般hash算法的分散性,但这还并不能当做其被广泛应用的原由,因为还缺少了平衡性。下面将分析一致性哈希算法是如何满足平衡性的。hash算法是不保证平衡的,如上面只部署了NODE1和NODE3的情况(NODE2被删除的图),object1存储到了NODE1中,而object2、object3、object4都存储到了NODE3中,这样就照成了非常不平衡的状态。在一致性哈希算法中,为了尽可能的满足平衡性,其引入了虚拟节点。
——“虚拟节点”( virtual node )是实际节点(机器)在 hash 空间的复制品( replica ),一实际个节点(机器)对应了若干个“虚拟节点”,这个对应个数也成为“复制个数”,“虚拟节点”在 hash 空间中以hash值排列。
以上面只部署了NODE1和NODE3的情况(NODE2被删除的图)为例,之前的对象在机器上的分布很不均衡,现在我们以2个副本(复制个数)为例,这样整个hash环中就存在了4个虚拟节点,最后对象映射的关系图如下:
根据上图可知对象的映射关系:object1->NODE1-1,object2->NODE1-2,object3->NODE3-2,object4->NODE3-1。通过虚拟节点的引入,对象的分布就比较均衡了。那么在实际操作中,正真的对象查询是如何工作的呢?对象从hash到虚拟节点到实际节点的转换如下图:
“虚拟节点”的hash计算可以采用对应节点的IP地址加数字后缀的方式。例如假设NODE1的IP地址为192.168.1.100。引入“虚拟节点”前,计算 cache A 的 hash 值:
Hash(“192.168.1.100”);
引入“虚拟节点”后,计算“虚拟节”点NODE1-1和NODE1-2的hash值:
Hash(“192.168.1.100#1”); // NODE1-1
Hash(“192.168.1.100#2”); // NODE1-2
-
顶
- 32
-
踩
- 2
-
猜你在找
核心技术类目
全部主题
Hadoop
AWS
移动游戏
Java
Android
iOS
Swift
智能硬件
Docker
OpenStack
VPN
Spark
ERP
IE10
Eclipse
CRM
JavaScript
数据库
Ubuntu
NFC
WAP
jQuery
BI
HTML5
Spring
Apache
.NET
API
HTML
SDK
IIS
Fedora
XML
LBS
Unity
Splashtop
UML
components
Windows Mobile
Rails
QEMU
KDE
Cassandra
CloudStack
FTC
coremail
OPhone
CouchBase
云计算
iOS6
Rackspace
Web App
SpringSide
Maemo
Compuware
大数据
aptech
Perl
Tornado
Ruby
Hibernate
ThinkPHP
HBase
Pure
Solr
Angular
Cloud Foundry
Redis
Scala
Django
Bootstrap
- 个人资料
-
- 访问:431166次
- 积分:5925
- 等级:
- 排名:第1737名
- 原创:128篇
- 转载:134篇
- 译文:2篇
- 评论:210条
- 文章搜索
- 文章分类
- 阅读排行
- (39783)
- (15833)
- (13220)
- (12163)
- (11483)
- (11453)
- (10548)
- (9618)
- (9536)
- (9381)
- 评论排行
- (30)
- (25)
- (15)
- (15)
- (10)
- (10)
- (8)
- (7)
- (6)
- (6)
- 推荐文章
- 最新评论
: 楼主 没有这个SublimeClang/internals文件夹啊 这个是手动生成的吗
: 我很喜欢这篇文章。
: 我按照您的方法做了,但是我的进入到http://192.168.8.94/ganglia/后发现之后...
: 比POSIX多线程程序设计讲得还要容易理解
: 非常感谢!网上其他资料写的都不详细,SublimeClang官网下载的包里只有libclang.dl...
: @fl_csdn:keystone提供了更强的、更灵活的功能,且与swift的耦合性更低,至于具体的...
: 楼主,我想问一下,keystone认证和swauth认证有什么区别啊?
: 5分钟没看完,被打脸了
: @TonyLee1314:我也是,怎么解决啊!急死了,还有东西要做!
: 很不错的文章
Cynric 的博客
修身齐家治国平天下 格物致知诚意正己心
一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似。一致性哈希修正了CARP使用的简 单哈希算法带来的问题,使得分布式哈希(DHT)可以在P2P环境中真正得到应用。
一致性hash算法提出了在动态变化的Cache环境中,判定哈希算法好坏的四个定义:
1、平衡性(Balance):平衡性是指哈希的结果能够尽可能分布到所有的缓冲中去,这样可以使得所有的缓冲空间都得到利用。很多哈希算法都能够满足这一条件。
2、单调性(Monotonicity):单调性是指如果已经有一些内容通过哈希分派到了相应的缓冲中,又有新的缓冲加入到系统中。哈希的结果应能够保证原有已分配的内容可以被映射到原有的或者新的缓冲中去,而不会被映射到旧的缓冲集合中的其他缓冲区。
3、分散性(Spread):在分布式环境中,终端有可能看不到所有的缓冲,而是只能看到其中的一部分。当终端希望通过哈希过程将内容映射到缓冲上时,由于不同终端所见的缓冲范围有可能不同,从而导致哈希的结果不一致,最终的结果是相同的内容被不同的终端映射到不同的缓冲区中。这种情况显然是应该避免的,因为它导致相同内容被存储到不同缓冲中去,降低了系统存储的效率。分散性的定义就是上述情况发生的严重程度。好的哈希算法应能够尽量避免不一致的情况发生,也就是尽量降低分散性。
4、负载(Load):负载问题实际上是从另一个角度看待分散性问题。既然不同的终端可能将相同的内容映射到不同的缓冲区中,那么对于一个特定的缓冲区而言,也可能被不同的用户映射为不同 的内容。与分散性一样,这种情况也是应当避免的,因此好的哈希算法应能够尽量降低缓冲的负荷。
在分布式集群中,对机器的添加删除,或者机器故障后自动脱离集群这些操作是分布式集群管理最基本的功能。如果采用常用的hash(object)%N算法,那么在有机器添加或者删除后,很多原有的数据就无法找到了,这样严重的违反了单调性原则。接下来主要讲解一下一致性哈希算法是如何设计的:
环形Hash空间
按照常用的hash算法来将对应的key哈希到一个具有2^32次方个桶的空间中,即0~(2^32)-1的数字空间中。现在我们可以将这些数字头尾相连,想象成一个闭合的环形。如下图
把数据通过一定的hash算法处理后映射到环上
现在我们将object1、object2、object3、object4四个对象通过特定的Hash函数计算出对应的key值,然后散列到Hash环上。如下图:
Hash(object1) = key1;
Hash(object2) = key2;
Hash(object3) = key3;
Hash(object4) = key4;
将机器通过hash算法映射到环上
在采用一致性哈希算法的分布式集群中将新的机器加入,其原理是通过使用与对象存储一样的Hash算法将机器也映射到环中(一般情况下对机器的hash计算是采用机器的IP或者机器唯一的别名作为输入值),然后以顺时针的方向计算,将所有对象存储到离自己最近的机器中。
假设现在有NODE1,NODE2,NODE3三台机器,通过Hash算法得到对应的KEY值,映射到环中,其示意图如下:
Hash(NODE1) = KEY1;
Hash(NODE2) = KEY2;
Hash(NODE3) = KEY3;
通过上图可以看出对象与机器处于同一哈希空间中,这样按顺时针转动object1存储到了NODE1中,object3存储到了NODE2中,object2、object4存储到了NODE3中。在这样的部署环境中,hash环是不会变更的,因此,通过算出对象的hash值就能快速的定位到对应的机器中,这样就能找到对象真正的存储位置了。
机器的删除与添加
普通hash求余算法最为不妥的地方就是在有机器的添加或者删除之后会照成大量的对象存储位置失效,这样就大大的不满足单调性了。下面来分析一下一致性哈希算法是如何处理的。
1. 节点(机器)的删除
以上面的分布为例,如果NODE2出现故障被删除了,那么按照顺时针迁移的方法,object3将会被迁移到NODE3中,这样仅仅是object3的映射位置发生了变化,其它的对象没有任何的改动。如下图:
2. 节点(机器)的添加
如果往集群中添加一个新的节点NODE4,通过对应的哈希算法得到KEY4,并映射到环中,如下图:
通过按顺时针迁移的规则,那么object2被迁移到了NODE4中,其它对象还保持这原有的存储位置。通过对节点的添加和删除的分析,一致性哈希算法在保持了单调性的同时,还是数据的迁移达到了最小,这样的算法对分布式集群来说是非常合适的,避免了大量数据迁移,减小了服务器的的压力。
平衡性
根据上面的图解分析,一致性哈希算法满足了单调性和负载均衡的特性以及一般hash算法的分散性,但这还并不能当做其被广泛应用的原由,因为还缺少了平衡性。下面将分析一致性哈希算法是如何满足平衡性的。hash算法是不保证平衡的,如上面只部署了NODE1和NODE3的情况(NODE2被删除的图),object1存储到了NODE1中,而object2、object3、object4都存储到了NODE3中,这样就照成了非常不平衡的状态。在一致性哈希算法中,为了尽可能的满足平衡性,其引入了虚拟节点。
——“虚拟节点”( virtual node )是实际节点(机器)在 hash 空间的复制品( replica ),一实际个节点(机器)对应了若干个“虚拟节点”,这个对应个数也成为“复制个数”,“虚拟节点”在 hash 空间中以hash值排列。
以上面只部署了NODE1和NODE3的情况(NODE2被删除的图)为例,之前的对象在机器上的分布很不均衡,现在我们以2个副本(复制个数)为例,这样整个hash环中就存在了4个虚拟节点,最后对象映射的关系图如下:
根据上图可知对象的映射关系:object1->NODE1-1,object2->NODE1-2,object3->NODE3-2,object4->NODE3-1。通过虚拟节点的引入,对象的分布就比较均衡了。那么在实际操作中,正真的对象查询是如何工作的呢?对象从hash到虚拟节点到实际节点的转换如下图:
“虚拟节点”的hash计算可以采用对应节点的IP地址加数字后缀的方式。例如假设NODE1的IP地址为192.168.1.100。引入“虚拟节点”前,计算 cache A 的 hash 值:
Hash(“192.168.1.100”);
引入“虚拟节点”后,计算“虚拟节”点NODE1-1和NODE1-2的hash值:
Hash(“192.168.1.100#1”); // NODE1-1
Hash(“192.168.1.100#2”); // NODE1-2
-
顶
- 32
-
踩
- 2
-
猜你在找
-
20楼
吃素了 2015-05-15 01:17发表
- 5分钟没看完,被打脸了
-
19楼
51412 2015-04-26 11:28发表
- 博客中的图是用visio画的吗?
-
18楼
在读中大 2015-04-11 22:44发表
- 楼主的牛逼
-
17楼
he037 2015-04-11 15:46发表
- 假如新增节点,它的虚拟节点是怎么分布的啊,重新分布吗?重新分布那数据迁移也很大,不重新分布,那怎么保证平衡性的啊
- 回复he037:加入新节点时,会将该节点虚拟成多个虚节点,然后散列在环的不同位置中,最后将该环附近的数据迁移至该节点,已达到新的平衡。(一致性hash算法的主要目的是为了尽量减少数据迁移)
-
Re:
cywosp 2015-04-14 11:01发表
-
16楼
he037 2015-04-11 15:35发表
- 假如新增节点,虚拟节点会不会重新分布?如果重新分布那数据迁移量不是很大?
-
15楼
wellse 2015-03-30 19:24发表
- 图文结合很生动,理解了呵呵!
-
14楼
itfanr 2015-03-17 16:17发表
-
真心漂亮啊!
-
13楼
y0908105023 2015-03-16 11:05发表
- 单调性写错了
-
12楼
crystal_dan7 2015-03-11 16:08发表
- 想请教楼主,在引入虚节点后,也是会出现不平衡的情况吧?
-
10楼
jzhx107 2015-01-29 11:26发表
- 不错,谢谢楼主讲解!
-
9楼
展翅飞翔XD 2014-11-30 00:53发表
- 还是不知道怎么去实现,一般的hash算法都是32位(md5)甚至更多位,这样就不是2^32-1了啊,我想用php实现,博主能不能能个提示??如果有例子就更好了,先谢谢了!
- 回复展翅飞翔XD:计算的hash值(整数值)与 0x7FFFFFFF做 &运算不就完了。或者%
-
Re:
ohmygirl 2014-12-03 17:23发表
-
8楼
展翅飞翔XD 2014-11-30 00:51发表
- 我想用php去实现,但是想不出来要怎么做,2^32-1就是8个f的16进制数,但是用hash函数,一般都是32位(md5)甚至更多位,这样就不行了啊,难道要自己去写这个hash算法??博主能不能提示一下??如果有相关例子就更好了,先谢谢了!
-
7楼
华为cloudos 2014-04-15 08:57发表
- 5分钟看不完:)但是楼主讲的很好,赞
- 回复华为cloudos:熟悉相关概念之后 5分钟就能看完了
-
Re:
cywosp 2014-04-15 12:26发表
-
6楼
夏影2014 2014-04-14 10:56发表
- 感谢分享,现在正在学习中
-
5楼
守枫竹清 2014-04-12 13:19发表
- 谢谢了
-
3楼
一只蚂农 2014-04-11 10:21发表
- 很不错
-
1楼
SpeedMe 2014-04-11 06:41发表
- 先讲理论,后结合例子讲。总结的非常不错!很容易看懂。
核心技术类目
全部主题
Hadoop
AWS
移动游戏
Java
Android
iOS
Swift
智能硬件
Docker
OpenStack
VPN
Spark
ERP
IE10
Eclipse
CRM
JavaScript
数据库
Ubuntu
NFC
WAP
jQuery
BI
HTML5
Spring
Apache
.NET
API
HTML
SDK
IIS
Fedora
XML
LBS
Unity
Splashtop
UML
components
Windows Mobile
Rails
QEMU
KDE
Cassandra
CloudStack
FTC
coremail
OPhone
CouchBase
云计算
iOS6
Rackspace
Web App
SpringSide
Maemo
Compuware
大数据
aptech
Perl
Tornado
Ruby
Hibernate
ThinkPHP
HBase
Pure
Solr
Angular
Cloud Foundry
Redis
Scala
Django
Bootstrap
- 个人资料
-
- 访问:431166次
- 积分:5925
- 等级:
- 排名:第1737名
- 原创:128篇
- 转载:134篇
- 译文:2篇
- 评论:210条
- 文章搜索
- 文章分类
- 阅读排行
- (39783)
- (15833)
- (13220)
- (12163)
- (11483)
- (11453)
- (10548)
- (9618)
- (9536)
- (9381)
- 评论排行
- (30)
- (25)
- (15)
- (15)
- (10)
- (10)
- (8)
- (7)
- (6)
- (6)
- 推荐文章
- 最新评论
20楼 吃素了 2015-05-15 01:17发表 [回复]-
-
5分钟没看完,被打脸了
19楼 51412 2015-04-26 11:28发表 [回复]-
-
博客中的图是用visio画的吗?
Re: cywosp 2015-04-27 14:46发表 [回复]-
-
回复51412:不是,用office 2007 ppt
Re: 51412 2015-04-27 23:06发表 [回复]-
-
回复cywosp:使用ppt画的?
Re: cywosp 2015-04-28 09:41发表 [回复]-
-
回复51412:是的
Re: 51412 2015-04-28 15:41发表 [回复]-
-
回复cywosp: 使用ppt里的哪个功能画出来的?
18楼 在读中大 2015-04-11 22:44发表 [回复]-
-
楼主的牛逼
17楼 he037 2015-04-11 15:46发表 [回复]-
-
假如新增节点,它的虚拟节点是怎么分布的啊,重新分布吗?重新分布那数据迁移也很大,不重新分布,那怎么保证平衡性的啊
Re: cywosp 2015-04-14 11:01发表 [回复]-
-
回复he037:加入新节点时,会将该节点虚拟成多个虚节点,然后散列在环的不同位置中,最后将该环附近的数据迁移至该节点,已达到新的平衡。(一致性hash算法的主要目的是为了尽量减少数据迁移)
16楼 he037 2015-04-11 15:35发表 [回复]-
-
假如新增节点,虚拟节点会不会重新分布?如果重新分布那数据迁移量不是很大?
15楼 wellse 2015-03-30 19:24发表 [回复]-
-
图文结合很生动,理解了呵呵!
14楼 itfanr 2015-03-17 16:17发表 [回复]-
-
真心漂亮啊!
13楼 y0908105023 2015-03-16 11:05发表 [回复]-
-
单调性写错了
12楼 crystal_dan7 2015-03-11 16:08发表 [回复]-
-
想请教楼主,在引入虚节点后,也是会出现不平衡的情况吧?
11楼 雨天要吃饭 2015-01-30 11:52发表 [回复]-
-
博主的图是用什么工具画的 很漂亮
Re: cywosp 2015-01-30 16:09发表 [回复]-
-
回复雨天要吃饭:office 2010
10楼 jzhx107 2015-01-29 11:26发表 [回复]-
-
不错,谢谢楼主讲解!
9楼 展翅飞翔XD 2014-11-30 00:53发表 [回复]-
-
还是不知道怎么去实现,一般的hash算法都是32位(md5)甚至更多位,这样就不是2^32-1了啊,我想用php实现,博主能不能能个提示??如果有例子就更好了,先谢谢了!
Re: ohmygirl 2014-12-03 17:23发表 [回复]-
-
回复展翅飞翔XD:计算的hash值(整数值)与 0x7FFFFFFF做 &运算不就完了。或者%
8楼 展翅飞翔XD 2014-11-30 00:51发表 [回复]-
-
我想用php去实现,但是想不出来要怎么做,2^32-1就是8个f的16进制数,但是用hash函数,一般都是32位(md5)甚至更多位,这样就不行了啊,难道要自己去写这个hash算法??博主能不能提示一下??如果有相关例子就更好了,先谢谢了!
7楼 华为cloudos 2014-04-15 08:57发表 [回复]-
-
5分钟看不完:)但是楼主讲的很好,赞
Re: cywosp 2014-04-15 12:26发表 [回复]-
-
回复华为cloudos:熟悉相关概念之后 5分钟就能看完了
6楼 夏影2014 2014-04-14 10:56发表 [回复]-
-
感谢分享,现在正在学习中
5楼 守枫竹清 2014-04-12 13:19发表 [回复]-
-
谢谢了
4楼 博客管理员 2014-04-11 12:17发表 [回复]-
-
您的文章已被推荐到CSDN首页,感谢您的分享。
Re: cywosp 2014-04-15 12:25发表 [回复]-
-
回复博客管理员:谢谢
3楼 一只蚂农 2014-04-11 10:21发表 [回复]-
-
很不错
2楼 5iasp 2014-04-11 09:10发表 [回复]-
-
非常好,有java的例子吗? 学习了。
Re: cywosp 2014-04-15 12:26发表 [回复]-
-
回复5iasp:很抱歉,这个没有
1楼 SpeedMe 2014-04-11 06:41发表 [回复]-
-
先讲理论,后结合例子讲。总结的非常不错!很容易看懂。