Amazon Dynamo论文解读 — Dynamo数据划分算法

        由于公司将来的项目可能需要用到Amazon的DynamoDB数据库,所以,最近想花时间好好研究研究下DynamoDB, 而Amazon在发布DynamoDB前,曾向SISO提交了一篇Dynamo论文,而DynamoDB就是基于这篇论文而实现的,所以,为了对Dynamo有个更深刻的了解,我决定好好看看这篇论文,了解了解论文里的相关算法。
       这篇博客,就是基于我对这篇论文的理解,描述了论文中的算法之一,即Dynamo数据划分算法。
      先解释解释数据划分的概念,大家也许都知道,DynamoDB是一个分布式Nosql数据库,既然是分布式,那么要发挥它的威力,肯定要使用集群(多台机器搭建)了,既然是使用集群,我们肯定要考虑如何将数据合理的、高效的存放到各台机器上,才能保证各台机器负载的均衡性等问题。而数据划分算法就是一种描述数据如何被合理的划分到集群中各台机器上的算法,它也是目前AmazonDB中采用的一种数据划分算法。
 
     在详细描述Dynamo数据划分算法前,我们先了解一些常见的分布式数据划分算法:
     算法一:在一个分布式环境中,假如有N台机器, 最常见的,也是最简单的数据划分算法就是,我们根据数据的Key(数据的一个唯一标识)的哈希值,进行取模运算,根据计算结果决定将该数据存放在哪一台机器上。 例:假如 N=4, 数据A的key的Hash值为 11,则数据A存放在标识为 3(11%4=3)的机器上。
     存在的问题:在分布式系统中,横向扩展、容错性是很重要的指标,也就是说,在分布式系统中,可以根据系统的业务量随意的从集群中添加或移除机器。同时,机器出现异常也是常有的事,好的分布式系统必须保证,集群中的某台机器出现故障不会影响到整个系统的运行。 假如,由于业务量增大了,你需要往集群中增加一台或多台机器,以支撑业务的增张,此时由于机器N的变化,为了保证能采用方法顺利的读取到先前存取的数据,则你先前存储的数据必须全部重新进行取模运算,然后重新存储。 例如: 还是先前例子,先前 数据A存储在标识为3的机器上,读取时,从3上读取数据。假如你往集群里添加一台机器,N从4变成5, 此时你读取数据时,却从标识为1(11%5=1)的机器上读取数据,很显然,A不在1上,而在机器3上。所以,为了保证在N变成5后,你必须重新对A进行计算,重新存储A到标识为1的机器上。
 
    算法二:为了应对算法一所出现的问题,现在业界出现了一种新的数据划分算法,称作一致性哈希算法。该算法的思想是不仅对数据A的Key值进行hash,而且也对集群里的机器进行hash取值,然后结合两者的hash值进行数据划分。怎么结合呢?
    具体步骤有: 
    首先构造一个Hash环(例如下图一),然后根据一定的规则计算集群中每台机器的hash值,根据该hash值将该服务器分配到环上的某个位置;
    然后,计算你要存储的数据的hash值(key的hash值),然后,根据这个hash值在hash环上顺时针查找,知道找到第一个机器节点;
    最后,将该数据存储到找到的这台机器上。
    如上所描述,如果采用一致性hash算法时,当向集群里添加或删除(机器故障)一台机器时,它不会影响到整个集群,也就是说,添加或删除机器前的数据不需要全部重新进行取模运算,然后重新存储,而是只需要对添加或删除节点(机器,在环中看成一个节点)的前一个节点上的数据进行重新计算即可,这样就解决了方法一所存在的问题。 具体可参照图二
    存在的问题:
          1. 不能保证数据均匀的分布到集群中的各台机器上。试想想,假如在一致性hash环上,分布了A、B、C、D 四台机器,[A,B]间的数据分布在B上,[B,C]间的数据分布在C上,一次类推,假如啊,[A,B]间的数据特别多,而[B,C]间的数据特别少,这就导致了存储在B上的数据量很大,而C上的数据木有,这就是很明显的数据分布不均;
         2. 基本上完全忽略了机器的差异性,即机器B和C是有差别的,B假如存储是500G,而C是2T,如果B和C存储同样的数据450G,这就造成,B的存储负载较大,而C的资源又没得到充分的利用.
         3.  还是负载方面的问题,假如hash环上的某一个节点出现故障,按照先前的算法,则该节点上的数据则全部得迁移到前一节点,这样导致前一节点的负载压力突然变得很大。例如:假如C故障,C上的数据则全部迁移到B上,按照向前例子,则B上无法存储900G的数据(因为它的存储只有500G),这样,导致B也当掉.  注意: 在集群环境中,为了保证数据的有效性,数据都会有一个或多个副本存在.
                 

                                           图一 一致性has环                                                               图二 向hash环中添加一台机器


   算法三: dynamo数据划分算法。该算法是建立在算法二(一致性hash算法)至上的,为了就是解决算法二所存在的问题。算法三和算法二的不同之处是,它不再将集群中的一台机器当成一个节点而分布在hash环上了,而是引进了 虚拟节点这个概念,即一台机器对应多个虚拟节点,然后将虚拟节点合理的分布在环上的各个位置,这样,相当于一台机器分布在环上的多个位置, 机器配置高,则虚拟节点多,否则虚拟节点就少,这样,就解决了方法二中存在的第2点问题,因为虚拟节点的多少决定了一台机器所负责数据存储的范围。 同时,当一台机器出现故障,从集群中移除时,它上面存储的数据将被均匀的分配到其它节点上(因为,该机器对应多个虚拟节点,机器移除时,会将该机器上的数据全部分配到虚拟节点的前一个节点),当然,添加一台机器也是一样。
      最后,其实算法二相对简单点,用得也是相当的广,据说大名鼎鼎的分布式缓存memcached 采用的就是算法二的数据划分算法,算法三是不错,但感觉有点复杂,如怎么确定一台机器虚拟节点的个数?虚拟几点怎么样合理的划分到环上?等等。  
       好了,数据划分算法先说到这,后面我会继续贴出一些我对dynamo这篇论文的理解,因为这论文是值得学习的,著名的Nosql数据库cassandra也是基于这篇论文而实现的,你如果对cassandra感兴趣,我想也最后读读这篇论文。


    参考地址:http://www.allthingsdistributed.com/2007/10/amazons_dynamo.html   dynamo论文
                    http://www.cnblogs.com/liunx/archive/2010/03/24/1693925.html    一致性hash算法的描述

   
 
      

       
     

你可能感兴趣的:(Amazon Dynamo论文解读 — Dynamo数据划分算法)