解析DynamoDB

文 / 郭理靖

DynamoDB是Amazon最新发布的NoSQL产品。本文在介绍DynamoDB特性的基础上,将其与SimpleDB、Cassandra和MongoDB进行了分析和比较。

DynamoDB简介

在NoSQL概念日益火爆的今天,市场上又增加了一个重量级的NoSQL产品—DynamoDB,它是Amazon AWS于2012年1月18日发布的。一看到这个名称,很多人都会想起2007年Amazon发表的Dynamo论文。人们经常将这篇论文与Google的BigTable相提并论,这在当时带来了相当大的影响,很多产品都借鉴了Dynamo的思想,比如Cassandra。

那什么是DynamoDB呢?按照AWS CTO Werner Vogels的说法:“DynamoDB是一个性能好、可靠高且具有可扩展性的NoSQL云数据库服务,DynamoDB集15年分布式非关系性数据库开发之精粹,又通过内部使用考验,是AWS团队精心打造的产品。”本文将通过DynamoDB的特性、数据模型,以及API来进行深入的介绍。

从官方文档来看,DynamoDB有以下几个特性。

  • 稳定的性能保证。为了保证高性能,DynamoDB采用固态硬盘(SSD)进行存储,对于一般的请求,DynamoDB在十毫秒内就可以完成,而且处理请求的速度不会随着数据量的增加而减慢。
  • 读/写流量限制预设(Provisioned Throughput)。这个概念和我们经常接触的按带宽收费非常相像,用户必须指定对数据库的读/写带宽,Amazon会按用户设置的读/写带宽收费。但与传统的带宽收费不同,用户可以随时通过控制台或者API更改数据库的读/写流量的限制。
  • 自动扩容。DynamoDB不会对用户的数据规模大小做任何限制,后台会默默地把用户的数据分布到各个机器上去。
  • 强一致性。用户可以通过参数指定要读的数据是否需要一致性。这里需要注意的是,如果读的数据全是要求强一致性的话,那么在设置读流量上限时需要设置成实际读流量的两倍。
  • 完全分布式,无中心化架构。一个表上的数据可以分布到几百台机器上。
  • Schema free。都叫NoSQL了,Schema必须free。
  • 和Amazon Elastic MapReduce深度整合。在EMR上可以调用DynamoDB的数据进行MapReduce,并将计算结果保存到S3,同时也可以用EMR对DynamoDB做备份。
  • 容灾。容错、完善的监控、安全、物美价廉、管理方便,这些都是云服务应该做到的。

大家第一眼看到Provisioned Throughput时,都会觉得这个概念比较别扭。为什么要给自己限制读/写流量呢?但仔细分析之后大家会发现Provisioned Throughput是迫不得已的做法,而且前三个特性其实也与之有着不可分割的关联。

DynamoDB是一个共享型的数据库云服务。所谓共享型的数据库云服务,是指一台机器上的CPU、内存及磁盘资源会给多用户使用。共享型服务最大的问题在于资源的公平性,如何保证一个用户对资源的使用不会影响到其他用户?例如,用户A在DynamoDB上保存了10GB的数据,假设这10GB数据全部保存在同一台机器上,而且这台机器的读性能只有1GB/秒。此时,如果用户每秒要读1GB数据,必然会影响到其他用户对同台机器上的数据访问,因为一台机器的吞吐量是固定的。这样就没有办法做到每个用户每个请求都有稳定的性能保证。正如各种MySQL共享服务会根据用户预购买的数据空间来限定每秒的请求数来解决资源公平性一样,DynamoDB利用Provisioned Throughput来解决资源公平性。如果用户的读/写请求量变大,就得提高读/写请求的带宽上限,付更多的钱,DynamoDB同时会根据用户购买的带宽将数据分散到更多的机器上。目前,单表最多支持10000个1KB读/写(相当于10MB/s的读写),单用户最多20000个1KB读/写(相当于20MB/s的读写)。如果需求增加,则需要填表单独申请。同时还有更多详细的规定,具体详见用户手册(其实所有的规定都是受到资源公平性以及后台具体实现的约束)。

从DynamoDB的数据模型来看,Attribute、Item和Table是DynamoDB中的三个基本概念。

  • Attribute。一个Attribute是一个name-value对,其中value可以是string、number、string set、number set,比如:

“ID” = 1
“Title” = “Programmer”
“Tags” = “DynamoDB”, “AWS”, “CSDN”
“Ratings” = 6, 7, 5

  • Item。Item是由多个Attribute组成的,相当于一个JSON字符串,每个Item的Attribute不同,但同一个Table的Item都必须指定为Primary Key的Attribute。
  • Table。由多个Item组成,其概念和关系型数据库的Table类似,相当于MongoDB的Collecion。
  • DynamoDB并没有DB的概念,而且目前单用户最多只能创建256个Table。每个Table都必须要一个Primary Index。Index有两种Primary Key:Simple Hash Key和Composite Hash Key with Range Keys。
  • Simple Hash Key。这个Key对应的Attribute在每个Item里都必须存在而且唯一。
  • Composite Hash Key with Range Keys。顾名思义,在Hask Key的基础上,用户可以增加一个Attribute作为范围查询的Key。此时不需要保证Hash Key的唯一性,只需要这两个组合Key是唯一的就可以。这在我们做时间范围查询时非常有用,比如某个用户在24小时内访问过的网页。

DynamoDB共提供了11个API接口,如表1所示。

表1 DynamoDB提供的11个API接口

DynamoDB和SimpleDB的区别

熟悉Amazon AWS的朋友应该知道SimpleDB。细心的朋友还会发现,自DynamoDB上线以后,在AWS首页的Database列表中,只能看到RDS和DynamoDB,DynamoDB已经替换了SimpleDB原来在这个列表中的位置,似乎SimpleDB已被打入冷宫

SimpleDB是AWS上的第一个NoSQL数据库服务,AWS团队也在博客上详数SimpleDB几个致命的缺点,正是这些缺点导致AWS开发全新的数据库服务。

  • SimpleDB有单表限制。SimpleDB也有类似于Table的东西叫做Domain,每个Domain最多只能保存10GB的数据,而DynamoDB并没有单表存储的任何限制。虽然SimpleDB提供的Schema Free可以提高开发者的效率和灵活性,但10GB这种无法扩展的限制妨碍了很多开发者的使用,使得很多开发者采用了其他NoSQL解决方案。
  • 性能不稳定。SimpleDB以简单为设计目标,SimpleDB并不需要用户指定Primary Key,也不需要用户创建索引,会默认对所有Attribute创建索引。然而这种简洁性也带来了一些副作用:如果用户插入的一条数据带有非常多的Attribute,SimpleDB就需要去更新所有Attribute的索引,而且不管用户将来是否需要。真是所谓的:用或者不用,索引就在那里。正是由于默认对所有Attribute创建索引,整个Domain才会有10GB这么奇怪的限制,以避免数据量变得比较大时,创建索引的过程会变得极慢无比,根本不能忍受。而DynamoDB因为有了Provisioned Throughput的限制以及采用了固态硬盘,可以保证每个请求的性能是非常稳定而且高效的。
  • 一致性问题。SimpleDB设计时采用的是最终一致性模型,而DynamoDB读数据时用户可以选择弱一致性或者强一致性,对用户而言可以根据业务特征来进行选择,毕竟强一致性在逻辑上更容易让用户接受。

在Schema上,两者都不需要固定Schema,但value类型不够丰富,在API设计上DynamoDB继承了SimpleDB的风格,请求的参数个数显得比较臃肿,好在有不同语言的SDK,方便了用户的开发。

DynamoDB不是SimpleDB 2.0,但DynamoDB也吸收了SimpleDB以及其他NoSQL数据设计思想的精华,相信会有不少用户会采用DynamoDB作为他们的NoSQL解决方案。

DynamoDB和Cassandra、MongoDB的比较

前面说过Cassandra受2007年Amazon发表的Dynamo论文影响非常深,在DynamoDB发布的第一天,提供Cassandra商业化支持的DataStax公司的Jonathan Ellis就写了一篇文章,分析了Cassandra和DynamoDB的差异。在这里我将这两者和目前比较火的MongoDB放在一起进行比较,如表2所示。

表2 DynamoDB和Cassandra、MongoDB的比较

虽然Jonathan Ellis认为DynamoDB不支持Secondary Key Indexes是在开历史的倒车,但如果DynamoDB支持了Secondary Key Indexes,那么它是无法保证每个请求性能的高效性的。这和DynamoDB的设计理念相冲突,于是舍弃了这部分的功能。

其实从开发的易用角度来讲,DynamoDB没有Cassandra和MongoDB强大,Cassandra有CQL可以做非常丰富的查询,MongoDB的查询功能也非常强大,而且后两者都提供Shell客户端,并有不少第三方开发的工具可以进行管理与使用。在条件更新上,DynamoDB也没有MongoDB使用起来那么方便,并且MongoDB提供了更多的原子性操作。在对value类型的支持上,另两者都不如MongoDB,毕竟MongoDB是文档型的数据库,可以理解为底层存储的是JSON。毕竟,JSON支持的类型以及在JSON上可以做的操作是很丰富的。我一直觉得DynamoDB没有支持类JSON格式是个遗憾。也许可能是DynamoDB团队觉得如果支持类JSON格式的话,在API的设计上会显得更加臃肿和让用户更难理解API如何使用。但个人认为,DynamoDB如果提供相应的SDK其实是可以解决这个问题的,就算MongoDB的开放接口相对DynamoDB更加复杂,开发者都是直接使用驱动(相当于SDK)进行开发,于是在开发应用上MongoDB远胜于DynamoDB。

但从运维的角度来讲,DynamoDB省去开发者部署/监控/维护数据库环节,给开发者节约了大量时间,强大的扩展能力又减轻了后续运维的压力,这正是DynamoDB最大的价值所在。

 

作者郭理靖,盛大云计算云数据库产品部经理,负责开发MongoIC、数据库云等云端的数据库服务。曾就职于金山、淘宝等公司。

本文为《程序员》杂志2012年03期卷首语,更多精彩内容敬请关注03期杂志

《程序员》2012年杂志订阅送好礼活动火热进行中

你可能感兴趣的:(云计算)