本文主要是介绍Amazon的Dynamo研究,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Amazon的Dynamo研究
许多开源项目一种非开源项目,在做高并发的存储设计的时候都会用consistent hashing算法。这其中包括Memcached[1],以及Amazon的dynamo[2],所以先说说consistent hashing,那么,什么事一致性哈希呢?
我将使用amazon的dynamo中Key/value 来作为例子。传统的数据存储都是采用的数据库的形式,但是数据库的strong consistence导致availability很受限,很难满足amazon的高availability的要求,因为amazon要求任何时候,对任何客户,购物服务必须是availability,为了应对这种场景,amazon开发出了自己的dynamo系统。在dynamo中,各个数据都是通过主key进行检索的,即通过主key来检索出整个object(例如二进制的blob或者可读的clob)的,但是无论是何种场景,object中的数据都不是直接可以得到的,所以dynamo不支持想数据库的关联形式等复杂的检索。
至此,就不难想象,即使基本思想就是,通过对key进行hash,来找到其对应的cache的位置,然后从cache中读取value。
那么,怎么由key计算出对应的存储cache的host呢。amazon就是在consistent hashing做了一些变种。
简单想法
如果现在有5台机器,很容易想象出找到一台host的suanfa其实是 hostNo = key%5; 这种hash有一种致命的问题,就是加入新的机子,和移除一台机子的时候导致整个缓存的失效,容错性非常差,所以在实际中是没法使用的。
一致性哈希
所以可能的hash值组成一个闭环,所有的hash值将所在0和计算机所能表示的最大值之间(对于32位机,可以认为是2^32-1),就是说0~2^32-1~0组成一个闭环。
主机到hash值的映射
如果现在有5台机器,很容易想象出找到一台host的suanfa其实是 hostNo = key%5; 这种hash有一种致命的问题,就是加入新的机子,和移除一台机子的时候导致整个缓存的失效,容错性非常差,所以在实际中是没法使用的。
一致性hash就是说将所有可能的hash值组成一个环,这个环是0~2^32-1~0。
而对每台机子进行hash,比如对机子的主机名,ip或者mac地址进行hash,然后会得各自的hash值。
我们就以mac地址来作为例子来说明吧,由于每个mac地址是不重复的,那么hash出来的结果也是不重复的。
这样你的5台机子就得到了5个hash值,分别是:
hashValueA = hash(macA);
hashValueB =hash(macB)
hashValueC =hash(macC)
hashValueD =hash(macD)
hashValueE =hash(macE)
现在假如这个五个hash值的大小分别是hashValueA<hashValueB<hashValueC<hashValueD<hashValueE。那么这5个hash值将所有的hash值分成了5段,分别是,
( hashValueA, hashValueB ], ( hashValueB, hashValueC ], ( hashValueC, hashValueD ], ( hashValueD, hashValueE ], ( hashValueE, hashValueA ].
Object到主机的映射
这时候,假如你有一个对象,你怎么决定应该把它存到那台host上面呢?好的,hashValue = object.hash(),这样你得到了一个hash值,算法很见到,就是找到比hashValue大得第一个host的hash值。
现在假如 hashValue > hashValueC ,但是 hashValue < hashValueD 。
这就意味着,hashValue应该映射到hostD上。
一致性哈希分析
加入一台新机子
而当你加入一台新机子,比如hostF的时候,只需要移动很小一部分的cache,现在假如hashValueF > hashValueE,那么这时候,对象(hashValueE,hashValueF]的cache值存储于hostA上面,这时候我们需要把它移动到hostF上面。
删除一台机子
通过一致性,这样每当一台机子down机的时候,只是影响到很小的一部分hash值的cache的命中。
现在假设hostD挂掉了,那什么只有hash位于( hashValueC, hashValueD ]的这些对象受到影响。
但是这时候仍然会造成cache的数据的丢失。可见一致性hash解决了scalability的问题,但是没有解决Availability的问题以及consistency的问题。
Dynamo的Replica for Availability
Dynamo通过Replica来实现Availability。也就是说把数据放在cache到对台host上面,而不是只是一台host,这样当一台机子失效时,可以通过去其他的机子读取数据来保证availability。
Dynamo采用的是consistent hash的变种。每当存储一份数据时,consistent hash只是把数据放在hash值比本身大的第一台host上面,而dynamo会将数据存储到前N台host上面。还以前面的例子来说明(即object的hash值hashValue满足, hashValue > hashValueC ,但是 hashValue < hashValueD ),假设这时候N是3,那么应该将这份数据存储到主机D, E, A三台机子上面,而不是仅仅存储到主机D上面,这就保证了availability。
但是要保证保证了availability,那么consistency就要受到牺牲。
Dynamo的Replica for Availability
Dynamo使用gossip协议来发现数据中的不一种性,而通过vector clock来尽量的解决冲突。并通过Quorum的方法来实现一定程度的最终一致性。
这部分会在以后补充。
引文
- http://memcached.org/
- http://www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf
这篇关于Amazon的Dynamo研究的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!