`
san_yun
  • 浏览: 2663762 次
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

Dynamo 简介

 
阅读更多

这个小文打算写成入门级的介绍,所以很多语言不追求准确性。本介绍参考 Amazon 的 Dynamo 论文。需要更详细更准确信息的同学请直接阅读原文。(原文地址http://s3.amazonaws.com /AllThingsDistributed/sosp/amazon-dynamo-sosp2007.pdf) 这篇论文本身没提出什么新的思想,正如论文中所说,贡献在于把非常多的技术结合到了一起,来完成一个系统。

 

    Dynamo 是个什么东东呢?他是 Amazon 公司的一个分布式 key/value 存储引擎。那么这个什么引擎又是什么?首先,假设一个场景,你的网站要存储用户登陆的ip。这个问题怎么解决呢?传统的方法是用数据库。数据库提供了方便 的操作接口,复杂的查询能力以及事物的保证。多好的解决方案啊。尽管应用不需要什么复杂查询,也不需要事物。好,现在假设大家都很喜欢你的网站,访问的人 越来越多。一个数据库已经处理不过来了。于是你安装了3台数据库主机,把用户分成了三类(男人,女人,it人;总是有某种方法把用户分成数目大致差不多的 几个部分吧)。每次访问的时候,先看用户属于哪一类,然后直接访问存储那类用户数据的数据库。于是处理能力增加了三倍。这个时候你已经实现了一个分布式的 存储引擎,Dynamo 就是一个类似的东西。只是它的可靠性,可用性等方面更好一点而已。下面我们看看那个简单的分布式存储系统有什么不方便的地方,而Dynamo是如何解决 的。


    先列举一下简单的分布式系统可能存在的问题吧:
    1 很难扩容:如果现在业务发展迅速,3台主机撑不住了,需要加到5台主机,那要如何处理呢?首先要更改分类方法,把用户分成5类,然后重新迁移已经存在的数 据。你要在网站上贴个条子,“系统维护中”,然后开始伟大的迁移工程,等到终于迁移完成,发现其实3台也不用了,用户都走光了。
    2 数据可靠性无法保证:有一天,发现有一台数据库服务器的硬盘坏了。麻烦了,本来网站就不赚钱,没用什么高档机器,只有一个定期的增量备份而已。经过一天复杂的恢复工作,你还要对部分用户说,麻烦你们把做过的事情再做一遍啊
    3 单点问题:负责把用户分类,然后决定使用哪个数据服务器的那台主机是网站的命根子啊,它如果宕机,所有的数据都不能访问了,它如果满负荷了,增加数据服务器也不会对整体性能有帮助。我好像看到一台贴满着驱邪保平安符咒的pc server。

    这几个问题,看似不大,解决起来还真的不容易呢。尤其是想到自己的网站也许有一天也会和google有一样多的用户(可能因为你是天才或者google快倒闭了)。现在我们看看 Dynnamo 是怎么解决的吧。

 

    1 扩容问题:这个问题实际上是数据分布方式的问题(怎么分组)。最简单最容易想到的就是根据资源数目对数据进行哈希分布,比如算出一个哈希值,然后对资源数 取模。这种简单处理的结果就是当资源数变化的时候,每个数据重新取模后,其分布方式都可能变化,从而需要迁移大量的数据。举个简单的例子来说明一下,假设 我的数据是自然数(1-20),资源现在是三台主机(A,B,C),采用取模分配方式,那么分配后A主机的数据为 (1,4,7,10,13,16,19),B为(2,5,8,11,14,17,20) C(3,6,9,12,15,18)  现在增加一台主机D,重新分布后的结果是A(1,5,9,13,17) B(2,6,10,14,18) C(3,7,11,15,19) D(4,8,12,15,20) 可以看到,有大量的数据需要从一台主机迁移到另外一台主机。这个迁移过程是很消耗性能的。需要找到一种方式来尽可能减少对现存数据的影响(没有影响当然也 不可能,那说明新添加的主机没有数据)。Dynamo 采用的是 consistent hashing 来解决这个问题的。那么我们先来了解一下什么是consistent hashing。先想象一个圆,或者你自己的手表表面,把它看成是一个首尾相接的数轴,现在我们的数据,自然数,已经分布到这个圆上了,我们可以把我们的 资源采用某种方式,随机的分布到这个圆上(图1-1)。

 

 

 

现在我们让每一个资源负责它和上一个资源之间的数据,就是说A来负责区间(C,A],B来负责区间(A,B],C负责区间(B,C]。采用这种策 略,当我们增加一个资源主机的时候,比如D(图1-2),那么我们只需要影响新节点相邻的节点A所负责的范围(只需要将A中(C,D]这个区间的数据迁移 到D上)就可以了。因为资源节点是随机分布到数据圆上的,所以当资源节点的数量足够多的时候,可以认为每个节点的负载基本是均衡的。这是原始的 consistent hashing,Dynamo并没有采用这个模型。这个理想的理论模型跟现实之间有一个问题,在这个理论模型上,每个资源节点的能力是一样的。我的意思 是,他们有相同的cpu,内存,硬盘等,也就是有相同的处理能力。可现实世界,我们使用的资源却各有不同,新买的n核机器和老的奔腾主机一起为了节约成本 而合作。如果只是这么简单的把机器直接分布上去,性能高的机器得不到充分利用,性能低的机器处理不过来。这个问题怎么解决呢?Dynamo 使用的方法是虚节点。把上面的A B C等都想象成一个逻辑上的节点。一台真实的物理节点可能会包含几个虚节点(逻辑节点),也可能只包含一个,看机器的性能而定。等等,好像我们的网站还没发 展成 google 呢,我们能使用的硬件资源还不多,比如就4台主机。这个时候采用上面的方式,把资源随机分布上去,几乎一定会不均衡。这要怎么办呢?我们可以把那个数据圆 分成Q等份(每一个等份就是一个虚节点),这个Q要远大于我们的资源数。现在假设我们有S个资源,那么每个资源就承担Q/S个等份。 当一个资源节点离开系统的时候,它所负责的等份要重新均分到其他资源节点上, 一个新节点加入的时候,要从其他的节点”偷”到一定数额的等份。 这个策略下,当一个节点离开系统的时候,虽然需要影响到很多节点,但是注意,迁移的数据总量只是离开那个节点的数据量。同样,一个新节点的加入,迁移的数 据总量也只是一个新节点的数据量。之所以有这个效果是因为Q的存在,使得增加和减少机器的时候不需要对已有的数据做重新哈希。这个策略的要求是 Q>>S(其实还有存储备份的问题,现在还没介绍到,假设每个数据存储N个备份 则要满足Q>>S*N)。如果业务快速发展,使得不断的增加主机,从而导致Q不再满足Q>>S,那么这个策略将不断的退化。 (Dynamo 论文在 section 6。2 比较了三种策略的状况 ,本文只是简单介绍其思想,不是详细翻译)

 

    2 数据的可靠性:因为我们使用的是廉价的pc机,硬盘损毁或者是其他原因导致的主机不可用是很经常的事情。做这样一个估算,假设一台pc机平均三年就会有一 次失效,不可用。那么当一个一千台机器的集群,基本上每天都有机器坏掉,所以某主机不可用是常态,系统必须可以在这样的情况下继续提供服务(哦 虽然你的网站现在刚刚只需要4台主机,可是别忘了,它要成长成为google的)。当然,廉价pc的好处就是便宜。所以我们可以增加系统中数据的备份来使 得系统在某台机器挂掉的时候仍旧可用。大家最先想到的方案可能就是对每个节点,建立一个备份节点,如果主节点坏掉了,备份节点可以立刻顶上去(双机热 备)。但是仔细想一下,这个方案是让人不放心的。因为当一主一备中的某一台机器坏掉,另外一台就成了一个单点运行的节点。这个时候另外一个节点一旦发生错 误,服务就变得不可用,数据也有可能丢失。在一个要求高可靠性的系统上,这是不可忍受的。我们刚刚估算了一个大的集群每天都有机器挂掉。而这种错误,一定 要人工介入才能解决。想想系统管理员每天在机房里更换主机的情景以及其他不可预料情况(系统管理员休假或者新买的主机没按时到货等),再想想系统每天都有 节点在单点运行,真的是很可怕的事情。事实上,一般工业界认为比较安全的备份数应该是3份。好,那么我们看看做这个备份的时候需要注意的问题。首先,如何 选择备份节点。我们可以简单的选择顺序上的后两个节点为备份节点,比如存在节点A的数据,备份到节点B和C。但是当我们前面引入了虚节点的概念的时候就要 注意了,有可能C节点和A节点在同一台物理机器上,这个时候就不能选择C做为A的备份了。下一个问题,当一个节点离开系统的时候,比如宕机,这个节点上存 储的信息需要继续备份到其它节点上。虽然节点离开了系统,但是因为备份的存在,我们通过其他节点可以恢复出本节点的所有信息,因为该节点的离开,这部分信 息的备份数会比要求的备份数少一,所以需要把这部分数据做再备份。同样,当一个节点加入系统,从其他节点偷了数据后,其他节点也需要相应减少备份数。而一 个节点如果只是暂时性的不可达,也就是失效一个很短的时间(这种情况是最常发生的),那么需要其他节点暂时接管这个节点的工作,在其可用的时候,把数据增 量传送回该节点。在设计上述需求的解决方案的时候,还要考虑一个问题,各个节点间数据备份是同步还是异步。假设我们要求写请求总是尽可能的成功,那么我们 的策略是写任何一个节点成功就认为成功。节点之间的数据通过异步形式达成一致。这个时候读请求可能读不到最新写进去的信息,比如我们一个数据在A B C 三个节点各存一份(系统中有三个备份的时候,下面的讨论都是基于这个假设的),那么当写A成功后,另外一个进程从节点C读数据,这个时候C还没收到最新的 数据,只能给读请求一个较老的版本。这个可能会带来大问题;同样,如果我们希望读请求总能读到正确的数据,那我们的策略是写的时候要等A B C三个节点都写成功了才认为写成功。这个时候写请求可能要耗较多的时间,甚至根本不能完成(如果有节点不可达)也就是说,系统的一致性,可靠性,原子性, 隔离性的问题(ACID)是无法同时达到的。只能在其中做出取舍。Dynamo 的处理方式是把这个选择权交给用户,这就是它的N W R模型。N代表N个备份,W代表要写入至少W份才认为成功,R表示至少读取R个备份。配置的时候要求W+R > N。 因为W+R > N, 所以 R > N-W 这个是什么意思呢?就是读取的份数一定要比总备份数减去确保写成功的倍数的差值要大。也就是说,每次读取,都至少读取到一个最新的版本。注1 从而不会读到一份旧数据。当我们需要高可写的环境的时候(论文中举例,amazon的购物车的添加请求应该是永远不被拒绝的)我们可以配置W = 1 如果N=3 那么R = 3。 这个时候只要写任何节点成功就认为成功,但是读的时候必须从所有的节点都读出数据。如果我们要求读的高效率,我们可以配置 W=N R=1。这个时候任何一个节点读成功就认为成功,但是写的时候必须写所有三个节点成功才认为成功。大家注意,一个操作的耗时是几个并行操作中最慢一个的耗 时。比如R=3的时候,实际上是向三个节点同时发了读请求,要三个节点都返回结果才能认为成功。假设某个节点的响应很慢,它就会严重拖累一个读操作的响应 速度。


        这里我们需要讨论一下数据版本问题,这个问题不仅仅存在于分布式系统,只是分布式系统的一些要求使得这个问题更复杂。先看个简单的例子,用户x对 key1做了一次写入操作,我们设值是数字3。然后用户y读取了key1,这个时候用户y知道的值是3。然后用户x对值做了一个+1操作,将新值写入,现 在key1的值是4了。而用户y也做了一次+1操作,然后写入,因为用户y读到的值是3,y不知道这个值现在已经变化了,结果按照语义本应该是5的值,现 在还是4。解决这个问题常用的方法是设置一个版本值。用户x第一次写入key1 值3的时候,产生一个版本设为v1。用户y读取的信息中包括版本编号v1。当x做了加1把值4写入的时候,告诉server自己拿到的是版本v1,要在 v1的基础上把值改成4。server发现自己保存的版本的确是v1所以就同意这个写入,并且把版本改成v2。这个时候y也要写入4,并且宣称自己是在版 本v1上做的修改。但是因为server发现自己手里已经是版本v2了,所以server就拒绝y的写入请求,告诉y,版本错误。这个算法在版本冲突的时 候经常被使用。但是刚才我们描述的分布式系统不能简单采用这个方式来实现。假设我们设置了N=3 W=1。现在x写入key1 值3,这个请求被节点A处理,生成了v1版本的数据。然后x用户又在版本v1上进行了一次key1值4的写操作,这个请求这次是节点C处理的。但是节点C 还没有收到上一个A接收的版本(数据备份是异步进行的)如果按照上面的算法,他应该拒绝这个请求,因为他不了解版本v1的信息。但是实际上是不可以拒绝 的,因为如果C拒绝了写请求,实际上W=1这个配置,这个服务器向客户做出的承诺将被打破,从而使得系统的行为退化成W=N的形式。那么C接收了这个请 求,就可能产生前面提到的不一致性。如何解决这个问题呢?Dynamo 的方法是保留所有这些版本,用vector clock记录版本信息。当读取操作发生的时候返回多个版本,由客户端的业务层来解决这个冲突合并各个版本。当然客户端也可以选择最简单的策略,就是最近 一次的写覆盖以前的写。这里又引入了一个vector clock算法,这里简单介绍一下。可以把这个vector clock想象成每个节点都记录自己的版本信息,而一个数据,包含所有这些版本信息。来看一个例子:假设一个写请求,第一次被节点A处理了。节点A会增加 一个版本信息(A,1)。我们把这个时候的数据记做D1(A,1)。 然后另外一个对同样key(这一段讨论都是针对同样的key的)的请求还是被A处理了于是有D2(A,2)。这个时候,D2是可以覆盖D1的,不会有冲突 产生。现在我们假设D2传播到了所有节点(B和C),B和C收到的数据不是从客户产生的,而是别人复制给他们的,所以他们不产生新的版本信息,所以现在B 和C都持有数据D2(A,2)。好,继续,又一个请求,被B处理了,生成数据D3(A,2;B,1),因为这是一个新版本的数据,被B处理,所以要增加B 的版本信息。假设D3没有传播到C的时候又一个请求被C处理记做D4(A,2;C,1)。假设在这些版本没有传播开来以前,有一个读取操作,我们要记得, 我们的W=1 那么R=N=3,所以R会从所有三个节点上读,在这个例子中将读到三个版本。A上的D2(A,2);B上的D3(A,2;B,1);C上的D4(A,2; C,1)这个时候可以判断出,D2已经是旧版本,可以舍弃,但是D3和D4都是新版本,需要应用自己去合并。如果需要高可写性,就要处理这种合并问题。好 假设应用完成了冲入解决,这里就是合并D3和D4版本,然后重新做了写入,假设是B处理这个请求,于是有D5(A,2;B,2;C,1);这个版本将可以 覆盖掉D1-D4那四个版本。这个例子只举了一个客户的请求在被不同节点处理时候的情况, 而且每次写更新都是可接受的,大家可以自己更深入的演算一下几个并发客户的情况,以及用一个旧版本做更新的情况.
        上面问题看似好像可以通过在三个节点里选择一个主节点来解决,所有的读取和写入都从主节点来进行.但是这样就违背了W=1这个约定,实际上还是退化到 W=N的情况了.所以如果系统不需要很大的弹性,W=N为所有应用都接受,那么系统的设计上可以得到很大的简化.Dynamo 为了给出充分的弹性而被设计成完全的对等集群(peer to peer),网络中的任何一个节点都不是特殊的.

    3 单点问题:这个问题的解决要求系统构建的时候是去中心化的。在我们最初的简单系统里有一个中心节点,这个单点的存在使得系统在这一点上变得很脆弱。解决方 法就是让系统的每个节点都可以承担起所有需要的功能。这个问题的解决涉及到事情比较多,大和尚在这方面也是刚刚起步,就不打算做过多的介绍了。 Dynamo有Seed节点的概念。

    最后再次强调,这个东东只是对原文的部分主题做了一些简化的解释,也许有理解错误的地方,请感兴趣的同学阅读原文。
    注1,最近发现这个地方是有问题的, 这里所说的实际上是一个理想情况, 系统对外提供了强一致性, 实际上在实现的时候, 为了各种均衡的考虑, 并没有真正这样实现, Dynamo提供最终一致性.也就是说, 并不能保证立刻就可以读到新版本, 而是有一定的时间窗.

 

原文:http://rdc.taobao.com/blog/cs/?cat=11

分享到:
评论

相关推荐

    深入研究Cassandra后重读Dynamo

    #### 二、Dynamo架构简介及问题分析 **1. Consistent Hashing的问题** Dynamo采用了基于一致哈希(Consistent Hashing)的分区策略来实现数据分布。具体来说,它利用环状拓扑结构将数据映射到不同的节点上。尽管这种...

    Dynamo_pokerphp_

    【Dynamo_pokerphp_简介】 "Dynamo_pokerphp_"是一个专为扑克游戏设计的PHP框架,它允许开发者创建各种在线扑克平台,提供了一个高效、灵活的环境来构建和定制扑克游戏。标题中的"Dynamo"可能指的是这个框架的核心...

    PyPI 官网下载 | cdk-dynamo-table-view-0.1.89.tar.gz

    2. `README.md`或`README.rst`:通常包含了项目简介、安装指南、使用示例以及贡献者信息等。这是了解项目功能和如何开始使用的首要文档。 3. `src/`或`lib/`:包含项目的源代码,其中可能有一个或多个Python模块,...

    分布式存储技术简介.pptx

    "分布式存储技术简介" 分布式存储技术是指将数据分布式存储在多个节点上,以提高数据的可靠性、可用性和安全性。它可以解决传统存储方式中存在的许多问题,如存储空间不足、数据丢失和单点故障等。 集中存储结构是...

    NoSQL数据库技术实战

    涵盖的内容有:NoSQL与大数据简介、NoSQL的数据一致性、NoSQL的水平扩展与其他基础知识、BigTable与Google云计算原理、Google云计算的开源版本——Hadoop、Dynamo:Amazon的高可用键值对存储、LevelDb——出自Google...

    18个Java开源CMS系统一览.doc

    - 可与Tomcat、ATG Dynamo、WebLogic及WebSphere等多种应用服务器配合使用。 - 新版本提供了模板引擎、JSP支持以及连接管理系统等增强功能,进一步提高了系统的稳定性和灵活性。 #### 4. JBossNukes - **简介**: ...

    DeltaV Operate组态工具小技巧

    **功能简介** DeltaV Usersettings 是一个非常实用的功能,可以帮助用户适应不同的屏幕尺寸。特别是在面对宽屏显示器时,这一功能尤为重要。 **使用方法** 在设置中勾选 **Bypass16:10 Panel Layout** 选项,即可...

    NoSQL数据库类型简介

    键值数据库起源于 Amazon 开发的 Dynamo 系统,可以把它理解为一个分布式的 Hashmap,支持 SET/GET 元操作。 它使用一个哈希表,表中的 Key(键)用来定位 Value(值),即存储和检索具体的 Value。数据库不能对 Val

    云计算第二版

    3.1.1 Dynamo在Amazon服务平台的地位 88 3.1.2 Dynamo架构的主要技术 89 3.2 弹性计算云EC2 97 3.2.1 EC2的主要特性 97 3.2.2 EC2基本架构及主要概念 97 3.2.3 EC2的关键技术 99 3.3.4 EC2安全及容错机制 101 3.3 ...

    cassandra tuner设计文档1

    【Cassandra 系统简介】 Cassandra 是一款开源的分布式 NoSQL 数据库系统,源于 Facebook,旨在处理大规模的简单格式数据,如收件箱。它融合了 Google BigTable 的数据模型和 Amazon Dynamo 的完全分布式架构。自 ...

    NoSQL数据库笔谈

    最终一致性Key Value存储 Amazon之Dynamo 功能特色 架构特色 BeansDB 简介 更新 特性 性能 Nuclear 两个设计上的T ips Voldemort Dynomite Kai 未分类 Skynet Drizzle 比较 可扩展性 数据和查询模型 持久化设计 5. ...

    redis实战redis实战redis实战redis实战

    在介绍Redis的实战内容时,首先需要了解它的一些基础概念,比如Key-Value存储系统简介。Key-Value存储系统是一种以“键值对”的形式存储数据的数据库系统。在这个章节中,会提及一些其他的Key-Value存储系统,例如...

    Redis实战《红丸出品》

    ##### 1.1 Key-Value存储系统简介 在《Redis实战》中,作者红丸首先介绍了几种常见的Key-Value存储系统,包括Voldemort、Dynamo、memcachedb、Cassandra、memcached和Hypertable。这些系统各有特色,如Voldemort以...

    Redis实战 中文完成版

    #### 一、Key-Value存储系统简介 ##### 1.1.1 Voldemort Voldemort是一款分布式Key-Value存储系统,主要用于处理大规模数据存储的需求。它设计之初就是为了能够应对高并发读写场景,并且支持容错机制。与Redis相比...

    NoSQL数据库系统-Cassandra分布式结构化数据存储视频教程

    它最初由Facebook开发,用于储存收件箱等简单格式数据,集GoogleBigTable的数据模型与Amazon Dynamo的完全分布式的架构于一身Facebook于2008将 Cassandra 开源,此后,由于Cassandra良好的可扩展性,被等知名网站所...

    NoSQL数据库学习教程.pdf

    简介是指分布式系统的简介和总结。 更新是指分布式系统的更新和维护。 特性是指分布式系统的特点和优势。 性能Nuclear是指使用Nuclear来实现分布式系统的性能优化。 两个设计上的 Tips是指分布式系统的设计上的...

    redis学习指南开发大全.pdf

    2. **Key-Value存储系统的比较**:文档中提到了其他一些Key-Value存储系统,如Voldemort、Dynamo、memcached、Cassandra和Hypertable,这些系统与Redis在功能和设计上各有异同。 3. **选择Key-Value Store的原因**...

    Cassandra在360的实践与改进(22页).pdf

    一、Cassandra特点简介 1. 数据模型:Cassandra采用键值对存储,支持ColumnFamily、SuperColumn和Column。其数据模型设计灵活,适合大规模数据存储。 2. 分布式架构:Cassandra基于一致性哈希,实现去中心化的数据...

    Windows下的Cassandra 安装图文教程

    它是一个网络社交云计算方面理想的数据库,以 Amazon 专有的完全分布式的 Dynamo 为基础,结合了 Google BigTable 基于列族(Column Family)的数据模型。 Cassandra 的主要特点 ------------------- * 模式灵活:...

Global site tag (gtag.js) - Google Analytics