AWS DynamoDB教程之一:简介


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

AWS DynamoDB
AWS DynamoDB

AWS DynamoDB系列教程:

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两个部分组成。而这两个部分可以重复,只要其组合不重复就可以了。比如:

csv
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

bash
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


文章作者: 逻思
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 逻思 !