分布式系统基础-一致性哈希

注意: 本文是读者在理解了一致性哈希算法之后,写的一些感悟.由于参考的大多数资料都是英文文献,所以可能会有部分理解的与原文有差异.在文末附上了一些参考文献,其中便有作者读的Standford CS168的一篇文档,请读者在阅读时适当结合英文原文.当然,也有的中文资料写的也不错,我看过一篇.但是考虑到自己动手记录下才能更加加深印象,所以写成此文.文笔拙劣,当读者们见笑了.

很早就对分布式系统感兴趣,但是一直没有深入研究,一是因为忙着做其他事情,二是并没有什么书籍能够全面的介绍分布式系统中常用的算法.

Google了一番之后,发现有人说** Amazon的Dynamo**论文中,比较详细的介绍了分布式系统算法.于是就打算读这篇论文,把这篇论文中的算法学习一下.

我们先了解一下什么是** Dynamo**.从Wikipedia上我们可以看到其定义为:

通俗一点的讲,就是一个Key/Value存储系统,与其类似的产品还有Consul, Etcd, Zookeeper.

论文中第一个看到的算法就是** Consistent Hash**,中文译法便是一致性哈希.

那么这个算法的作用是什么呢?它能容忍集群的变动,使得即使集群中新增或者删除了节点,我们能够通过最小的代价来进行调整.** Dynamo**的论文中指出,它们使用这个算法来实现数据的分区和备份.

一致性哈希的使用场景

最开始,一致性哈希是被用在设计分布式缓存系统中.关于缓存,我们已经了解的够多了.这里就不详细介绍了.

当然,其使用场景远远不止于缓存系统.实际上,其在大量分布式系统中都有使用.

传统算法的不足

当设计一个分布式缓存系统时,关于数据的分布问题,最容易想到的解决方案便是,对key取Hash,转换成一个32位的数字,然后将其mod节点的数量,决定放在哪个节点中.这种方案在集群拓扑比较稳定时,是一个不错的方案.但是,如果我们新增一个节点,便会是一个灾难性的变化.比如,我们采用md5(key).toUInt32().mod(node_size)这个算法来计算节点的位置,原先有100个节点,key为AAAAAAA的那个数据,原先是放在node1上的.当我们想要读取这个key对应的数据时,我们可以通过md5("AAAAAAA").toUInt32.mod(100)这个函数来得到存在node1上,然后去对应的node1上找.现在问题来了,如果集群中新增了一个节点,现在节点数变为了101,那我们通过md5("AAAAAAA").toUInt32.mod(101)这个函数得到的结果就可能是node2,这当然会造成miss.然而,实际上这个数据还是缓存在整个集群中的.

我们可以看到,上面的算法的主要不足是,当新增了节点时,由于计算存储的节点依赖于节点的数量,所以在读缓存时,会造成明明数据存在却miss的情况.

一致性哈希的基本思想

我们知道,在一个集群中,可用节点的数量是一直在变得,这就导致传统算法的弊端被放大.基于此,Karger和其他专家提出了一致性哈希算法.那么它是如何解决出现传统的算法中的不足呢?

在我们考试的时候,考场的门上都贴着这个考场中考生的考号的范围.我们在进考场时,就得找到包含我们的考号的那个考场.

其实一致性哈希的实现方法就跟这个类似.

在一致性哈希中,我们除了需要计算要存储的数据的key的hash之外,还要计算节点的hash,然后在存储时,选择一个跟key的hash最接近的节点,存储进去.

比如说,AAAAAAA这个key的hash是100,我们还是有100个节点,其中第一个节点的hash值是10000, 第二个节点的hash值是20000,依次类推.那么要存储AAAAAAA这个key的节点就是第一个节点.

我们可以看到,第一个节点能够存放从hash值为0-10000 的key,第二个节点能够存放hash值为10001-20000的key.依次类推.

如果我们想要读取key为AAAAAAA的数据,经过计算,从节点1中读取即可.即使我们新增了第101个节点,还是从节点1中读取.

这张图片来自斯坦福大学cs168课程的一份文档中.

上图中的前缀为s的节点,表示集群中的一个节点,前缀为x的节点,表示要被缓存的数据.从第一张圆圈中,我们可以看到,由于x1, x2的hash值里s0最近,所以被存到s0这台节点中了,同理,x0被存到了s2这个节点中了.

在第二个圆圈中,由于多了一台节点,s3, 而x2现在又离它最近,所以,x2需要从s0节点迁移到s3中.

从上图中,我们也能看到,尽管一致性哈希解决了由于集群变动而导致的数据不命中率增加的问题,但是又引入了另一个复杂的问题,就是每个节点的负载不相同,因为每个节点的hash是根据IP计算出来的.

那一致性哈希是如何解决这个问题的呢?

虚节点

一致性哈希中,是通过虚节点来解决这个问题的.所谓的虚节点,顾名思义,就是虚拟的节点.那它到底是什么呢?之前我们在介绍一致性哈希的时候,是将物理节点直接通过哈希运算得到其hash值,而后数据的key计算出来之后,与节点的哈希进行比较,决定存放在哪个节点中.而现在,我们用几个虚拟节点代表一个物理节点.不同虚拟节点的hash是通过不同的哈希函数计算出来的.比如,上图中的三个物理节点,如果每个物理节点有四个虚拟节点的话,经过不同的哈希函数计算,可能得到的结果就是这样了:

这样,通过添加虚节点的方式,就能在一定程度上平衡各个节点的负载.

参考资料

Distributed Systems Part-1: A peek into consistent hashing!

CASSANDRADATABASELABS
Consistent Hashing in Cassandra

Standford CS168 Consistency Hash

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,158评论 4 370
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,600评论 1 307
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,785评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,655评论 0 220
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,075评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,002评论 1 225
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,146评论 2 318
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,918评论 0 211
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,671评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,838评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,318评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,636评论 3 263
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,343评论 3 244
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,187评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,982评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,126评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,934评论 2 279

推荐阅读更多精彩内容