作为AWS众多云服务的核心成员之一,DynamoDB得到了非常广泛的应用。下面就通过一系列教程来介绍一下DynamoDB的使用。

AWS DynamoDB系列教程:
- AWS DynamoDB系列之一:简介
- AWS DynamoDB教程之二:主键的设计及GSI
- AWS DynamoDB系列之三:Streams
- AWS DynamoDB系列之四:在Node.js中访问DynamoDB
- AWS DynamoDB系列之五:在本地安装DynamoDB
- AWS DynamoDB教程之六:如何使用APIGateway Service Proxy访问DynamoDB数据
- AWS DynamoDB教程之七:DynamoDB的访问控制
- AWS DynamoDB教程之八:数据备份/恢复及导出
- AWS DynamoDB教程之九:性能监测和调优,Audit Table及TTL
AWS DynamoDB介绍
DynamoDB是AWS旗下的一款NoSQL数据库。和众多AWS服务一样,它可以根据负载弹性伸缩。和传统关系型数据库相比较,由于其是基于键值对进行存储的,因此DynamoDB的访问速度非常快。但需要注意的是,DynamoDB有其限制,它只适用于仅通过固定模式访问数据的应用场景,而不适合具备复杂关系的数据集合。还可以通过Streaming和其他的AWS服务有效结合。比如:定时将DynamoDB备份到S3。
SQL和NoSQL数据库的区别
SQL | NoSQL |
---|---|
针对存储做的优化 | 针对性能做的优化 |
单步查询 | 即刻获取数据 |
Scale vertically | Scale horizontally |
更适合联机分析处理OLAP | 更适合联机事务处理OLTP |
DynamoDB的主要特点
- 由AWS完全管理的NoSQL,用户只需使用
- 适合文档,或者超宽的字段
- 对于任何流量的访问,性能稳定
- 超级快速和稳定
- 能够和AWS访问控制结合,甚至到行/字段级
- 适合事件驱动的程序设计
DynamoDB和RD的主要区别
这两种数据库的设计思路是截然不同的。
对于RDS来说,首先需要考虑的是表之间的关系。在将来需要访问数据的时候,可以采用更为灵活的方式获取数据。如果将要进行关系型查询,比如分组(group by)等,则需要RDS。同时,如果需要对各个字段的类型进行限制时,需要使用RDS的schema。在RDS中,可以使用强大的SQL来查询。
但对于DynamoDB来说,则首先需要考虑访问数据的方式,才能确定PK和SK。因此需要事先知道用于访问的Key。综合而论,DynamoDB强在稳定的高性能,但弱在灵活的访问方式。DynamoDB的优势在于,无论数据量增长的有多快,其性能会一直非常稳定。相较而言,对于RDS,当数据量过大时,其性能就会下降,而性能调优就有些类似一个黑盒子。
下面看一个具体的例子:
RDS
Scores
subjectId | studentId | date | score |
---|---|---|---|
01 | 9901 | xx | 90 |
02 | 9902 | xx | 80 |
Students
studentId | name | address | phone |
---|---|---|---|
9901 | Paul | xx | xx |
9902 | Liz | xx | xx |
可以看到,学生具体细节,比如地址,电话等只在Students表中保存一份。在Scores表中,通过studentId和Students连接。
DynamoDB
DynamoDB在通过键值组合访问数据时非常高效,但有可能会存在数据冗余。
subjectId | studentId | date | score | studentDetails |
---|---|---|---|---|
01 | 9901 | xx | 90 | JSON |
02 | 9902 | xx | 80 | JSON |
DynamoDB使用注意事项
善用PK/SK/GSI的组合
在涉及到一对多的关系时,可以通过PK/SK的组合来实现这个关系。
如果需要满足不同类型的查询时,可以考虑创建GSI。
关于每条Item的大小及其对查询结果的影响
在DyanmoDB中,无论如何分页,都要考虑到一个硬性限制:返回的数据大小不能超过1MB。这在有些时候会造成一些误解:问什么我的每页记录数为50,但只返回了30???一旦返回数据量超过了1MB,则不论如何分页,都不再继续返回数据。
关于Streams
这个功能非常强大,可以监测到每条记录的修改,进而触发相应的Lambda,实现业务逻辑。比如:实现DynamoDB到Opensearch的数据同步,自动记录所有DynamoDB的操作到日志中。
关于scan
这个功能比较鸡肋,被设计出来了,但似乎又没太大用处。当数据量较大的时候,任何应用都无法忍受其效率的。
核心概念
Table
DynamoDB中的表和传统关系型数据库中的表类似,也是一个数据的集合。
Item
Item就像关系型数据库中的记录,也就是一条记录。
Attribute
Attribute就等同于关系型数据库中的字段,也就是列。
Global Table
Global table其实就是一个Replica tables的集合。DynamoDB通过Streams保证各个表之间的数据同步。用户会和距离最近的表交互。
Global table的潜在问题:
- 如果某个区域的DynamoDB出现故障,在应用层需要考虑在不同区域间切换的问题。
- 在同步时可能发生写入的竞争关系
- 在跨越region时的数据一致性不能完全保证。
在使用Global table的时候需要完成以下几个步骤:
- 激活Stream
- Add region
- 确定选择On Demand或者Autoscaling
Primary Key,Partition Key和Sort Key
顾名思义,Primary Key是主键,不能重复。它由Partition Key和Sort Key两个部分组成。而这两个部分可以重复,只要其组合不重复就可以了。比如:
Student ID, Subject, Score, details
9901, Math, 90, JSON
9901, English, 90, JSON
9902, English, 80, JSON
9902, Physics, 88, JSON
在上面的数据中,Student ID(Partition Key)可以重复,Subject(Sort Key)也可以重复。但两者组合在一起的时候就形成了主键,就不能重复了。
在设计DynamoDB表结构的时候,如果Partition Key本身就不重复,那么可以单独使用Partition Key作为Primary Key,而无需使用Sort Key。
同时,上面例子中的details字段是一个JSON,其大小不应该超过400KB。
可以针对Sort Key进行各种查询:==, <, >, >=, <=, begins with, between, contains, in等。
Global Secondary Index (GSI)
在DynamoDB的设计理念中,只能针对事先设定好的键进行快速查询。但如果需要根据别的字段进行查询,则可以通过GSI来实现。比如:在前面的例子中,可以针对Score来建立一个GSI,这样就能满足类似如下的查询需求了:
找到所有分数大于90分的所有学生及科目信息。
当然,创建GSI的话就涉及到额外的费用。
关于Provisioned和On demand两种收费模式
Provisioned Capacity应该叫预置容量。也就是说事先买好容量,比如100 RCU/100 WCU。无论是否使用,都需要交付同样的费用。这种方式适合流量稳定的应用。一旦超出预先设定的流量,就会发生throttling,因此在选择时需要考虑这个因素。
如果流量稳定,但在不同时间段会有变化,应考虑使用Provisioned+Autoscaling。
而On demand则是按需收费,用多少收多少费。通过AWS的Autoscaling,自动调整。这种方式适合那种流量不可预知的应用。
创建自己DynamoDB表时的注意事项
- DynamoDB不会在不同区域间同步。因此在一个Region中创建的Table,在另一个Region中是不可见的。除非创建Globel Table,会自动在不同region之间同步。
- 一旦选择了Partition Key,就不可以更改。因此在创建之前要慎重考虑。
- 在选择Partition Key和Sort Key的时候,需要根据需求灵活设定。可能需要两者的组合,也可能只需要Partition Key来作为Primary Key。
- 关于付费方式的选择。如果有固定流量的话,可以选择”Provisioned”;如果流量不确定的话,可以选择”On Demand”。如果选择了”Provisioned”,则对应的Read/Write capacity意味着每秒的读取/写入数。
- 强烈推荐添加tags,这样在看账单的时候,就更加清晰了。其实在使用AWS时,不仅仅是DynamoDB,而是所有的AWS资源都应添加tags。
关于Partition Key的选择,请参考DynamoDB Developer Guide这句话:
“To get the most out of DynamoDB throughput, create tables where the partition key element has a large number of distinct values, and values are requested fairly uniformly, as randomly as possible.”
这样的话,在存储空间角度,对不同数据的访问被均匀分不到不同的key space。
客户端工具推荐
NoSQL Workbench
可以通过这个工具给DynamoDB建模,同时也可以连接DynamoDB。
DynamoDB Admin
官网:https://www.npmjs.com/package/dynamodb-admin
npm install -g dynamodb-admin
# For Windows:
set DYNAMO_ENDPOINT=http://localhost:8000
dynamodb-admin
# For Mac/Linux:
DYNAMO_ENDPOINT=http://localhost:8000 dynamodb-admin
DynamoDB GUI Client
这是基于Vue的纯客户端:https://awesomeopensource.com/project/Arattian/DynamoDb-GUI-Client