将 Amazon DynamoDB 数据库作为 AWS Database Migration Service的目标 - AWS 数据库迁移服务

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

将 Amazon DynamoDB 数据库作为 AWS Database Migration Service的目标

您可以使用将数据迁移 AWS DMS 到亚马逊 DynamoDB 表。Amazon DynamoDB 是一项完全托管的SQL无数据库服务,可提供快速、可预测的性能和无缝扩展。 AWS DMS 支持使用关系数据库或 MongoDB 作为源。

在 DynamoDB 中,表、项目和属性是您使用的核心组件。是项目的集合,而每个项目是属性的集合。DynamoDB 使用称为分区键的主键来唯一标识表中的各个项目。您还可以使用键和辅助索引来提供更具灵活性的查询。

您将使用对象映射将数据从源数据库迁移到目标 DynamoDB 表。使用对象映射可以确定源数据是否位于目标中。

在 DynamoDB 目标终端节点上 AWS DMS 创建表时,它会创建与源数据库终端节点中一样多的表。 AWS DMS 还会设置多个 DynamoDB 参数值。创建表的成本取决于要迁移的数据量和表数。

注意

AWS DMS 控制台上的 “SSL模式” 选项或 “API不适用于某些数据流” 和 “无” SQL 服务,例如 Kinesis 和 DynamoDB。默认情况下,它们是安全的,因此 AWS DMS 显示SSL模式设置等于无(SSLMode=None)。您无需为终端节点提供任何其他配置即可使用SSL。例如,使用 DynamoDB 作为目标端点时,默认情况下它是安全的。所有对 DynamoDB 的API调用都SSL使用,因此无需在终端节点中SSL添加其他选项。 AWS DMS 您可以使用协议安全地放置数据并通过SSL终端节点检索数据,该HTTPS协议在连接到 DynamoDB 数据库时默认 AWS DMS 使用。

为了帮助提高传输速度, AWS DMS 支持向 DynamoDB 目标实例进行多线程满载。 DMS支持这种多线程,其任务设置包括以下内容:

  • MaxFullLoadSubTasks— 使用此选项表示要并行加载的最大源表数。 DMS使用专用子任务将每个表加载到其相应的 DynamoDB 目标表中。默认值是 8。最大值为 49。

  • ParallelLoadThreads— 使用此选项指定用于将每个表加载到其 DynamoDB 目标表中的线程数。 AWS DMS 默认值是 0(单线程)。最大值为 200。您可以请求提高此最大值限制。

    注意

    DMS将表的每个段分配给其自己的线程进行加载。因此,将 ParallelLoadThreads 设置您为源中表指定的最大段数量。

  • ParallelLoadBufferSize – 使用此选项指定在缓冲区(并行加载线程将数据加载到 DynamoDB 目标时使用)中存储的最大记录数。默认值是 50。最大值为 1000。将此设置与 ParallelLoadThreads 一起使用;仅在有多个线程时 ParallelLoadBufferSize 才有效。

  • 各个表的 Table-mapping 设置 – 使用 table-settings 规则标识您希望并行加载的源中各个表。另外可使用这些规则来指定如何为多线程加载的每个表的行分段。有关更多信息,请参阅 表和集合设置规则和操作

注意

为迁移任务 AWS DMS 设置 DynamoDB 参数值时,默认读取容量单位 RCU () 参数值设置为 200。

还设置了 “写入容量单位” (WCU) 参数值,但其值取决于其他几个设置:

  • 该WCU参数的默认值为 200。

  • 如果ParallelLoadThreads任务设置设置为大于 1(默认值为 0),则该WCU参数将设置为该ParallelLoadThreads值的 200 倍。

  • 标准 AWS DMS 使用费适用于您使用的资源。

从关系数据库迁移到 DynamoDB 表

AWS DMS 支持将数据迁移到 DynamoDB 标量数据类型。从 Oracle 或 My 等关系数据库迁移SQL到 DynamoDB 时,您可能需要调整存储这些数据的方式。

目前 AWS DMS 支持从单表到单表重构为 DynamoDB 标量类型属性。如果您从关系数据库表迁移数据到 DynamoDB 中,您将从表中获取数据并将其重新格式化为 DynamoDB 标量数据类型属性。这些属性可以接受多个列中的数据,并且您可以直接将列映射到属性。

AWS DMS 支持以下 DynamoDB 标量数据类型:

  • String

  • 数字

  • 布尔值

注意

NULL来自源的数据在目标系统上会被忽略。

使用 DynamoDB 作为目标的先决条件 AWS Database Migration Service

在开始使用 DynamoDB 数据库作为目标 AWS DMS之前,请务必创建角色。IAM此IAM角色应允许代入并授予 AWS DMS 对要迁移到的 DynamoDB 表的访问权限。以下IAM策略中显示了最低访问权限集。

{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "dms.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }

您在迁移到 DynamoDB 时使用的角色必须具有以下权限:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "dynamodb:PutItem", "dynamodb:CreateTable", "dynamodb:DescribeTable", "dynamodb:DeleteTable", "dynamodb:DeleteItem", "dynamodb:UpdateItem" ], "Resource": [ "arn:aws:dynamodb:us-west-2:account-id:table/name1", "arn:aws:dynamodb:us-west-2:account-id:table/OtherName*", "arn:aws:dynamodb:us-west-2:account-id:table/awsdms_apply_exceptions", "arn:aws:dynamodb:us-west-2:account-id:table/awsdms_full_load_exceptions" ] }, { "Effect": "Allow", "Action": [ "dynamodb:ListTables" ], "Resource": "*" } ] }

使用 DynamoDB 作为目标时的限制 AWS Database Migration Service

将 DynamoDB 作为目标时存在以下限制:

  • DynamoDB 将数字数据类型的精度限制为 38 位。所有具有更高精度的数据类型应作为字符串存储。您需要使用对象映射功能明确指定这一点。

  • 由于 DynamoDB 没有日期数据类型,使用日期数据类型的数据将转换为字符串。

  • DynamoDB 不允许更新主键属性。当使用带更改数据捕获 (CDC) 的持续复制时,此限制非常重要,因为它可能会导致目标中出现不需要的数据。根据对象映射的方式,更新主键的CDC操作可以做以下两件事之一。它可能会失败,或插入具有更新后的主键和不完整数据的新项。

  • AWS DMS 仅支持复制具有非复合主键的表。当您为具有自定义分区键和/或排序键的目标表指定对象映射时除外。

  • AWS DMS 不支持LOB数据,除非它是CLOB. AWS DMS 迁移CLOB数据时将数据转换为 DynamoDB 字符串。

  • 使用 DynamoDB 作为目标时,仅 Apply Exceptions 控制表 (dmslogs.awsdms_apply_exceptions) 受支持。有关控制表的更多信息,请参阅控制表任务设置

  • AWS DMS 不支持将 Dynam TargetTablePrepMode=TRUNCATE_BEFORE_LOAD oDB 作为目标的任务设置。

  • AWS DMS 不支持将 Dynam TaskRecoveryTableEnabled oDB 作为目标的任务设置。

  • BatchApply不支持 DynamoDB 终端节点。

使用对象映射将数据迁移到 DynamoDB

AWS DMS 使用表映射规则将数据从源映射到目标 DynamoDB 表。要将数据映射到 DynamoDB 目标,您必须使用称为 object-mapping 的表映射规则类型。利用对象映射可以定义属性名称以及要迁移到其中的数据。您在使用对象映射时必须具有选择规则。

除了具有分区键和可选的排序键以外,DynamoDB 没有预设结构。如果您有非复合主键,请 AWS DMS 使用它。如果您有复合主键或者希望使用排序键,请在目标 DynamoDB 表中定义这些键以及其他属性。

要创建对象映射规则,您应将 rule-type 指定为 object-mapping。此规则指定您要使用的对象映射的类型。

规则的结构如下所示:

{ "rules": [ { "rule-type": "object-mapping", "rule-id": "<id>", "rule-name": "<name>", "rule-action": "<valid object-mapping rule action>", "object-locator": { "schema-name": "<case-sensitive schema name>", "table-name": "" }, "target-table-name": "<table_name>" } ] }

AWS DMS 目前支持将map-record-to-recordmap-record-to-document作为该rule-action参数的唯一有效值。这些值指定了默认情况下如何 AWS DMS 处理未排除在exclude-columns属性列表中的记录。这些值不会以任何方式影响属性映射。

  • 在从关系数据库迁移到 DynamoDB 时,可以使用 map-record-to-record。它使用关系数据库的主键作为 DynamoDB 中的分区键,并为源数据库中的每个列创建一个属性。使用时map-record-to-record,对于源表中未在exclude-columns属性列表中列出的任何列, AWS DMS 都会在目标 DynamoDB 实例上创建相应的属性。不论是否在属性映射中使用源列,都会执行此操作。

  • 使用 map-record-to-document 将源列放入目标上的、使用属性名称“_doc”的单个扁平化 DynamoDB 映射中。使用时map-record-to-document,将数据 AWS DMS 放入源上单个、平面的 DynamoDB 地图属性中。此属性称为“_doc”。此放置应用于源表中的未在 exclude-columns 属性列表中列出的任何列。

了解 rule-action 参数 map-record-to-recordmap-record-to-document 之间的差异的一种方法是,查看两个参数的实际使用情况。对于本示例,假定您使用关系数据库表行开始处理,该行具有以下结构和数据:

举例而言,示例数据库

要将此信息迁移到 DynamoDB,您将创建规则来将数据映射到 DynamoDB 表项目中。请注意为 exclude-columns 参数列出的列。这些列不直接映射到目标上;取而代之的是,属性映射用于将数据合并成新项目,例如将位置FirstName和分组LastName在一起以变成 CustomerNameDynamoDB 目标。 NickName收入不包括在内。

{ "rules": [ { "rule-type": "selection", "rule-id": "1", "rule-name": "1", "object-locator": { "schema-name": "test", "table-name": "%" }, "rule-action": "include" }, { "rule-type": "object-mapping", "rule-id": "2", "rule-name": "TransformToDDB", "rule-action": "map-record-to-record", "object-locator": { "schema-name": "test", "table-name": "customer" }, "target-table-name": "customer_t", "mapping-parameters": { "partition-key-name": "CustomerName", "exclude-columns": [ "FirstName", "LastName", "HomeAddress", "HomePhone", "WorkAddress", "WorkPhone" ], "attribute-mappings": [ { "target-attribute-name": "CustomerName", "attribute-type": "scalar", "attribute-sub-type": "string", "value": "${FirstName},${LastName}" }, { "target-attribute-name": "ContactDetails", "attribute-type": "document", "attribute-sub-type": "dynamodb-map", "value": { "M": { "Home": { "M": { "Address": { "S": "${HomeAddress}" }, "Phone": { "S": "${HomePhone}" } } }, "Work": { "M": { "Address": { "S": "${WorkAddress}" }, "Phone": { "S": "${WorkPhone}" } } } } } } ] } } ] }

通过使用rule-action参数 map-record-to-record,可以将数据NickName收入映射到 DynamoDB 目标中的同名项目。

开始使用 AWS DMS

但是,假设您使用相同的规则,但将rule-action参数更改为map-record-to-document。在这种情况下,exclude-columns参数中未列出的列NickName收入将映射到 _doc 项目。

开始使用 AWS DMS

使用自定义条件表达式和对象映射

您可以使用 DynamoDB 中称为条件表达式的功能来操作写入到 DynamoDB 表的数据。有关 DynamoDB 中条件表达式的更多信息,请参阅条件表达式

条件表达式成员包括:

  • 一个表达式 (必需)

  • 表达式属性值 (可选)。指定属性值的 DynamoDB json 结构

  • 表达式属性名 (可选)

  • 确定何时使用条件表达式的选项 (可选)。默认值为 apply-during-cdc = false 和 apply-during-full-load = true

规则的结构如下所示:

"target-table-name": "customer_t", "mapping-parameters": { "partition-key-name": "CustomerName", "condition-expression": { "expression":"<conditional expression>", "expression-attribute-values": [ { "name":"<attribute name>", "value":<attribute value> } ], "apply-during-cdc":<optional Boolean value>, "apply-during-full-load": <optional Boolean value> }

下面的示例强调了用于条件表达式的部分。

开始使用 AWS DMS

使用属性映射和对象映射

利用属性映射可以使用源列名来指定模板字符串,以便重建目标上数据的结构。除了用户在模板中指定的内容以外,不进行任何其他格式设置。

以下示例显示了源数据库的结构和所需的 DynamoDB 目标结构。首先显示的是源结构,在本例中为 Oracle 数据库,然后显示 DynamoDB 中所需的数据结构。该示例最后以JSON用于创建所需目标结构的。

Oracle 数据的结构如下所示:

FirstName LastName StoreId HomeAddress HomePhone WorkAddress WorkPhone DateOfBirth
主键 不适用
Randy Marsh 5 221B Baker Street 1234567890 31 Spooner Street, Quahog 9876543210 02/29/1988

DynamoDB 数据的结构如下所示:

CustomerName StoreId ContactDetails DateOfBirth
分区键 排序键 不适用
Randy,Marsh
5
{ "Name": "Randy", "Home": { "Address": "221B Baker Street", "Phone": 1234567890 }, "Work": { "Address": "31 Spooner Street, Quahog", "Phone": 9876541230 } }
02/29/1988

下面JSON显示了用于实现 DynamoDB 结构的对象映射和列映射:

{ "rules": [ { "rule-type": "selection", "rule-id": "1", "rule-name": "1", "object-locator": { "schema-name": "test", "table-name": "%" }, "rule-action": "include" }, { "rule-type": "object-mapping", "rule-id": "2", "rule-name": "TransformToDDB", "rule-action": "map-record-to-record", "object-locator": { "schema-name": "test", "table-name": "customer" }, "target-table-name": "customer_t", "mapping-parameters": { "partition-key-name": "CustomerName", "sort-key-name": "StoreId", "exclude-columns": [ "FirstName", "LastName", "HomeAddress", "HomePhone", "WorkAddress", "WorkPhone" ], "attribute-mappings": [ { "target-attribute-name": "CustomerName", "attribute-type": "scalar", "attribute-sub-type": "string", "value": "${FirstName},${LastName}" }, { "target-attribute-name": "StoreId", "attribute-type": "scalar", "attribute-sub-type": "string", "value": "${StoreId}" }, { "target-attribute-name": "ContactDetails", "attribute-type": "scalar", "attribute-sub-type": "string", "value": "{\"Name\":\"${FirstName}\",\"Home\":{\"Address\":\"${HomeAddress}\",\"Phone\":\"${HomePhone}\"}, \"Work\":{\"Address\":\"${WorkAddress}\",\"Phone\":\"${WorkPhone}\"}}" } ] } } ] }

使用列映射的另一种方法是使用 DynamoDB 格式作为您的文档类型。以下代码示例将 dynamodb-map 作为属性映射的 attribute-sub-type

{ "rules": [ { "rule-type": "selection", "rule-id": "1", "rule-name": "1", "object-locator": { "schema-name": "test", "table-name": "%" }, "rule-action": "include" }, { "rule-type": "object-mapping", "rule-id": "2", "rule-name": "TransformToDDB", "rule-action": "map-record-to-record", "object-locator": { "schema-name": "test", "table-name": "customer" }, "target-table-name": "customer_t", "mapping-parameters": { "partition-key-name": "CustomerName", "sort-key-name": "StoreId", "exclude-columns": [ "FirstName", "LastName", "HomeAddress", "HomePhone", "WorkAddress", "WorkPhone" ], "attribute-mappings": [ { "target-attribute-name": "CustomerName", "attribute-type": "scalar", "attribute-sub-type": "string", "value": "${FirstName},${LastName}" }, { "target-attribute-name": "StoreId", "attribute-type": "scalar", "attribute-sub-type": "string", "value": "${StoreId}" }, { "target-attribute-name": "ContactDetails", "attribute-type": "document", "attribute-sub-type": "dynamodb-map", "value": { "M": { "Name": { "S": "${FirstName}" }, "Home": { "M": { "Address": { "S": "${HomeAddress}" }, "Phone": { "S": "${HomePhone}" } } }, "Work": { "M": { "Address": { "S": "${WorkAddress}" }, "Phone": { "S": "${WorkPhone}" } } } } } } ] } } ] }

作为替代方案dynamodb-map,您可以使用dynamodb-list作为 f attribute-sub-type or 属性映射,如以下示例所示。

{ "target-attribute-name": "ContactDetailsList", "attribute-type": "document", "attribute-sub-type": "dynamodb-list", "value": { "L": [ { "N": "${FirstName}" }, { "N": "${HomeAddress}" }, { "N": "${HomePhone}" }, { "N": "${WorkAddress}" }, { "N": "${WorkPhone}" } ] } }

示例 1:使用属性映射和对象映射

以下示例将数据从两个 “我的SQL数据库” 表(nfl_data 和 sp ort_team)迁移到两个名为和的 Dyn amoDB 表。NFLTeamsSportTeams表的结构以及JSON用于将数据从 “我的SQL数据库” 表映射到 DynamoDB 表的结构如下所示。

我的SQL数据库表 nfl_data 的结构如下所示:

mysql> desc nfl_data; +---------------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------------+-------------+------+-----+---------+-------+ | Position | varchar(5) | YES | | NULL | | | player_number | smallint(6) | YES | | NULL | | | Name | varchar(40) | YES | | NULL | | | status | varchar(10) | YES | | NULL | | | stat1 | varchar(10) | YES | | NULL | | | stat1_val | varchar(10) | YES | | NULL | | | stat2 | varchar(10) | YES | | NULL | | | stat2_val | varchar(10) | YES | | NULL | | | stat3 | varchar(10) | YES | | NULL | | | stat3_val | varchar(10) | YES | | NULL | | | stat4 | varchar(10) | YES | | NULL | | | stat4_val | varchar(10) | YES | | NULL | | | team | varchar(10) | YES | | NULL | | +---------------+-------------+------+-----+---------+-------+

我的SQL数据库表 s port_team 的结构如下所示:

mysql> desc sport_team; +---------------------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +---------------------------+--------------+------+-----+---------+----------------+ | id | mediumint(9) | NO | PRI | NULL | auto_increment | | name | varchar(30) | NO | | NULL | | | abbreviated_name | varchar(10) | YES | | NULL | | | home_field_id | smallint(6) | YES | MUL | NULL | | | sport_type_name | varchar(15) | NO | MUL | NULL | | | sport_league_short_name | varchar(10) | NO | | NULL | | | sport_division_short_name | varchar(10) | YES | | NULL | |

将这两个表映射到两个 DynamoDB 表时使用的表映射规则如下所示:

{ "rules":[ { "rule-type": "selection", "rule-id": "1", "rule-name": "1", "object-locator": { "schema-name": "dms_sample", "table-name": "nfl_data" }, "rule-action": "include" }, { "rule-type": "selection", "rule-id": "2", "rule-name": "2", "object-locator": { "schema-name": "dms_sample", "table-name": "sport_team" }, "rule-action": "include" }, { "rule-type":"object-mapping", "rule-id":"3", "rule-name":"MapNFLData", "rule-action":"map-record-to-record", "object-locator":{ "schema-name":"dms_sample", "table-name":"nfl_data" }, "target-table-name":"NFLTeams", "mapping-parameters":{ "partition-key-name":"Team", "sort-key-name":"PlayerName", "exclude-columns": [ "player_number", "team", "name" ], "attribute-mappings":[ { "target-attribute-name":"Team", "attribute-type":"scalar", "attribute-sub-type":"string", "value":"${team}" }, { "target-attribute-name":"PlayerName", "attribute-type":"scalar", "attribute-sub-type":"string", "value":"${name}" }, { "target-attribute-name":"PlayerInfo", "attribute-type":"scalar", "attribute-sub-type":"string", "value":"{\"Number\": \"${player_number}\",\"Position\": \"${Position}\",\"Status\": \"${status}\",\"Stats\": {\"Stat1\": \"${stat1}:${stat1_val}\",\"Stat2\": \"${stat2}:${stat2_val}\",\"Stat3\": \"${stat3}:${ stat3_val}\",\"Stat4\": \"${stat4}:${stat4_val}\"}" } ] } }, { "rule-type":"object-mapping", "rule-id":"4", "rule-name":"MapSportTeam", "rule-action":"map-record-to-record", "object-locator":{ "schema-name":"dms_sample", "table-name":"sport_team" }, "target-table-name":"SportTeams", "mapping-parameters":{ "partition-key-name":"TeamName", "exclude-columns": [ "name", "id" ], "attribute-mappings":[ { "target-attribute-name":"TeamName", "attribute-type":"scalar", "attribute-sub-type":"string", "value":"${name}" }, { "target-attribute-name":"TeamInfo", "attribute-type":"scalar", "attribute-sub-type":"string", "value":"{\"League\": \"${sport_league_short_name}\",\"Division\": \"${sport_division_short_name}\"}" } ] } } ] }

NFLTeamsDynamoDB 表的示例输出如下所示:

"PlayerInfo": "{\"Number\": \"6\",\"Position\": \"P\",\"Status\": \"ACT\",\"Stats\": {\"Stat1\": \"PUNTS:73\",\"Stat2\": \"AVG:46\",\"Stat3\": \"LNG:67\",\"Stat4\": \"IN 20:31\"}", "PlayerName": "Allen, Ryan", "Position": "P", "stat1": "PUNTS", "stat1_val": "73", "stat2": "AVG", "stat2_val": "46", "stat3": "LNG", "stat3_val": "67", "stat4": "IN 20", "stat4_val": "31", "status": "ACT", "Team": "NE" }

SportsTeams DynamoDB 表的示例输出如下所示:

{ "abbreviated_name": "IND", "home_field_id": 53, "sport_division_short_name": "AFC South", "sport_league_short_name": "NFL", "sport_type_name": "football", "TeamInfo": "{\"League\": \"NFL\",\"Division\": \"AFC South\"}", "TeamName": "Indianapolis Colts" }

DynamoDB 的目标数据类型

的 DynamoDB 终端节点 AWS DMS 支持大多数 DynamoDB 数据类型。下表显示了使用时支持的 Amazon AWS DMS 目标数据类型 AWS DMS 以及 AWS DMS 数据类型的默认映射。

有关 AWS DMS 数据类型的更多信息,请参见AWS Database Migration Service 的数据类型

AWS DMS 迁移来自异构数据库的数据时,我们会将源数据库中的数据类型映射到称为 AWS DMS 数据类型的中间数据类型。然后,我们将中间数据类型映射到目标数据类型。下表显示了每种 AWS DMS 数据类型及其在 DynamoDB 中映射到的数据类型:

AWS DMS 数据类型 DynamoDB 数据类型

String

字符串

WString

String

布尔值

布尔值

日期

String

DateTime

String

INT1

数字

INT2

数字

INT4

数字

INT8

数字

数值

数字

Real4

数字

Real8

数字

UINT1

数字

UINT2

数字

UINT4

数字

UINT8 数字
CLOB String