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

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

将 Amazon Neptune 作为 AWS Database Migration Service 的目标

Amazon Neptune 是一项快速、可靠且完全托管式的图数据库服务,可帮助您轻松构建和运行适用于高度互连数据集的应用程序。Neptune 的核心是一个专门打造的高性能图形数据库引擎。该引擎经过优化,可存储数十亿个关系并能以毫秒级延迟进行图形查询。Neptune 支持常见的图形查询语言 Apache TinkerPop Gremlin 和 W3C SPARQL。有关 Amazon Neptune 的更多信息,请参阅《Amazon Neptune 用户指南》中的 Amazon Neptune 是什么?

如果没有图形数据库(如 Neptune),您可以在关系数据库中对高度互连的数据进行建模。由于数据具有潜在的动态关联,因此使用此类数据源的应用程序必须在 SQL 中为关联的数据查询建模。此方法要求您编写额外的层以将图形查询转换为 SQL。此外,关系数据库附带了架构刚度。为对更改连接建模而在架构中进行任何更改都需要停机时间以及对查询转换的额外维护,以支持新架构。查询性能也是设计应用程序时需要考虑的另一大约束。

图形数据库可大大简化此类情况。丰富的图形查询层(Gremlin 或 SPARQL)和针对图形查询优化的索引提高了灵活性和性能,可将您从架构中解放出来。Amazon Neptune 图形数据库还具有企业功能,如静态加密、安全授权层、默认备份、多可用区支持、只读副本支持等。

利用 AWS DMS,您可以将用于对高度互连的图形进行建模的关系数据从任何受支持的 SQL 数据库的 DMS 源端点迁移到 Neptune 目标端点。

有关更多详细信息,请参阅以下内容。

将 Amazon Neptune 作为迁移目标的概述

在开始执行到 Neptune 目标的迁移之前,请在 AWS 账户中创建以下资源:

  • 目标端点的 Neptune 集群。

  • 源端点的 AWS DMS 支持的 SQL 关系数据库。

  • 目标端点的 Amazon S3 存储桶。在您的 Neptune 集群所在的同一 AWS 区域中创建此 S3 存储桶。AWS DMS 将此 S3 存储桶作为中间文件存储,以便存储它批量加载到 Neptune 数据库的目标数据。有关创建 S3 存储桶的更多信息,请参阅《Amazon Simple Storage Service 用户指南》中的创建存储桶

  • Neptune 集群所在的同一 VPC 中 S3 的虚拟私有云 (VPC) 端点。

  • 包含 IAM policy 的 AWS Identity and Access Management (IAM) 角色。此策略将指定目标终端节点的 S3 存储桶的 GetObjectPutObjectDeleteObjectListObject 权限。此角色由 AWS DMS 和 Neptune 代入,二者具有对目标 S3 存储桶和 Neptune 数据库的 IAM 访问权限。有关更多信息,请参阅创建 IAM 服务角色以便将 Amazon Neptune 作为目标进行访问

在获得这些资源后,设置和启动到 Neptune 目标的迁移类似于使用控制台或 DMS API 进行的任何完全加载迁移。但是,到 Neptune 目标的迁移需要一些独特的步骤。

将 AWS DMS 关系数据库迁移到 Neptune
  1. 创建复制实例,如创建复制实例中所述。

  2. 创建和测试源终端节点的 AWS DMS 支持的 SQL 关系数据库。

  3. 为 Neptune 数据库创建和测试目标端点。

    要将目标端点连接到 Neptune 数据库,请为 Neptune 集群端点或 Neptune 写入器实例端点指定服务器名称。此外,指定 AWS DMS 的 S3 存储桶文件夹来存储其中间文件,以便批量加载到 Neptune 数据库。

    迁移过程中,AWS DMS 将所有已迁移的目标数据存储在此 S3 存储桶文件夹中,直至达到您指定的最大文件大小。当此文件存储达到该最大大小时,AWS DMS 会将存储的 S3 数据批量加载到目标数据库中。它将清空此文件夹来支持存储任何其他目标数据,以便随后将该数据加载到目标数据库。有关指定这些设置的更多信息,请参阅指定将 Amazon Neptune 作为目标的端点设置

  4. 使用步骤 1-3 中创建的资源创建完全加载复制任务,然后执行以下操作:

    1. 像往常一样使用任务表映射来标识特定的源架构、表和视图,以便使用适当的选择和转换规则从关系数据库中迁移。有关更多信息,请参阅使用表映射指定任务设置

    2. 通过选择下列选项之一指定源表和视图到 Neptune 目标数据库图形的映射规则,来指定目标映射:

      • Gremlin JSON – 有关使用 Gremlin JSON 加载 Neptune 数据库的信息,请参阅《Amazon Neptune 用户指南》中的 Gremlin 加载数据格式

      • SPARQL RDB 到资源描述框架映射语言 (R2RML) – 有关使用 SPARQL R2RML 的信息,请参阅 W3C 规范 R2RML:RDB 到 RDF 映射语言

    3. 请执行下列操作之一:

      • 使用 AWS DMS 控制台,使用创建数据库迁移任务页面上的图形映射规则指定图形映射选项。

      • 借助 AWS DMS API,使用 CreateReplicationTask API 调用的 TaskData 请求参数指定这些选项。

      有关使用 Gremlin JSON 和 SPARQL R2RML 指定图形映射规则的更多信息和示例,请参阅将 Amazon Neptune 作为目标使用时使用 Gremlin 和 R2RML 指定图形映射规则

  5. 开始复制迁移任务。

指定将 Amazon Neptune 作为目标的端点设置

要创建或修改目标终端节点,您可以使用控制台,也可以使用 CreateEndpointModifyEndpoint API 操作。

对于 AWS DMS 控制台中的 Neptune 目标,请在创建端点修改端点控制台页面上指定特定于端点的设置。对于 CreateEndpointModifyEndpoint,指定 NeptuneSettings 选项的请求参数。以下示例说明如何使用 CLI 执行此操作。

dms create-endpoint --endpoint-identifier my-neptune-target-endpoint --endpoint-type target --engine-name neptune --server-name my-neptune-db.cluster-cspckvklbvgf.us-east-1.neptune.amazonaws.com --port 8192 --neptune-settings '{"ServiceAccessRoleArn":"arn:aws:iam::123456789012:role/myNeptuneRole", "S3BucketName":"my-bucket", "S3BucketFolder":"my-bucket-folder", "ErrorRetryDuration":57, "MaxFileSize":100, "MaxRetryCount": 10, "IAMAuthEnabled":false}‘

在此处,CLI --server-name 选项指定 Neptune 集群写入器端点的服务器名称。也可以指定 Neptune 写入器实例端点的服务器名称。

--neptune-settings 选项请求参数如下所示:

  • ServiceAccessRoleArn –(必需)您为 Neptune 目标端点创建的服务角色的 Amazon 资源名称 (ARN)。有关更多信息,请参阅创建 IAM 服务角色以便将 Amazon Neptune 作为目标进行访问

  • S3BucketName –(必需)S3 存储桶的名称,在该存储桶中,在将迁移的图形数据批量加载到 Neptune 目标数据库之前,DMS 可以在 .csv 文件中临时存储这些图形数据。DMS 先将 SQL 源数据映射到图形数据,然后再将其存储在这些 .csv 文件中。

  • S3BucketFolder –(必需)您希望 DMS 将迁移的图形数据存储在由 S3BucketName 指定的 S3 存储桶中的文件夹路径。

  • ErrorRetryDuration –(可选)在引发错误之前,DMS 等待重试将已迁移的图形数据批量加载到 Neptune 目标数据库的毫秒数。默认值是 250。

  • MaxFileSize –(可选)DMS 将数据批量加载到 Neptune 目标数据库之前,存储在 .csv 文件中的已迁移图形数据的最大大小(以 KB 为单位)。默认值是 1048576 KB (1 GB)。如果成功,DMS 会清除存储桶,准备存储下一批迁移的图形数据。

  • MaxRetryCount –(可选)在引发错误之前,DMS 重试将已迁移的图形数据批量加载到 Neptune 目标数据库的次数。默认值是 5。

  • IAMAuthEnabled –(可选)如果要为此端点启用 IAM 授权,请将此参数设置为 true,并将相应的 IAM policy 文档附加到由 ServiceAccessRoleArn 指定的服务角色。默认值为 false

创建 IAM 服务角色以便将 Amazon Neptune 作为目标进行访问

要将 Neptune 作为目标进行访问,请使用 IAM 创建服务角色。根据您的 Neptune 端点配置,将下列部分或所有 IAM policy 和信任文档附加到此角色。在创建 Neptune 端点时,需提供此服务角色的 ARN。这样一来,AWS DMS 和 Amazon Neptune 便能代入权限以访问 Neptune 及其关联的 Amazon S3 存储桶。

如果您在 Neptune 端点配置中,将 NeptuneSettings 中的 IAMAuthEnabled 参数设置为 true,请将如下所示的 IAM policy 附加到服务角色。如果将 IAMAuthEnabled 设置为 false,则可忽略此策略。

// Policy to access Neptune { "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": "neptune-db:*", "Resource": "arn:aws:neptune-db:us-east-1:123456789012:cluster-CLG7H7FHK54AZGHEH6MNS55JKM/*" } ] }

前面的 IAM policy 允许对 Resource 指定的 Neptune 目标集群进行完全访问。

将如下所示的 IAM 策略附加到服务角色。此策略允许 DMS 将迁移的图形数据临时存储在创建的 S3 存储桶中,该存储桶用于将数据批量加载到 Neptune 目标数据库中。

//Policy to access S3 bucket { "Version": "2012-10-17", "Statement": [{ "Sid": "ListObjectsInBucket0", "Effect": "Allow", "Action": "s3:ListBucket", "Resource": [ "arn:aws:s3:::my-bucket" ] }, { "Sid": "AllObjectActions", "Effect": "Allow", "Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::my-bucket/" ] }, { "Sid": "ListObjectsInBucket1", "Effect": "Allow", "Action": "s3:ListBucket", "Resource": [ "arn:aws:s3:::my-bucket", "arn:aws:s3:::my-bucket/" ] } ] }

前面的 IAM policy 允许您的账户查询为 Neptune 目标创建的 S3 存储桶 (arn:aws:s3:::my-bucket) 的内容。它还允许您的账户完全操作所有存储桶文件和文件夹的内容 (arn:aws:s3:::my-bucket/)。

编辑信任关系并将以下 IAM 角色附加到服务角色,以允许 AWS DMS 和 Amazon Neptune 数据库服务代入该角色。

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

有关为 Neptune 目标端点指定此服务角色的信息,请参阅指定将 Amazon Neptune 作为目标的端点设置

将 Amazon Neptune 作为目标使用时使用 Gremlin 和 R2RML 指定图形映射规则

您创建的图形映射规则指定如何将从 SQL 关系数据库源中提取的数据加载到 Neptune 数据库集群目标中。这些映射规则的格式各不相同,具体取决于规则是用于通过 Apache TinkerPop Gremlin 加载属性图形数据,还是用于通过 R2RML 加载资源描述框架 (RDF) 数据。在下文中,您可以找到有关这些格式的信息并查明可从何处了解更多信息。

在使用控制台或 DMS API 创建迁移任务时,可以指定这些映射规则。

使用控制台,使用创建数据库迁移任务页面上的图形映射规则指定这些映射规则。在图形映射规则中,可以使用提供的编辑器直接输入和编辑映射规则。或者,可以浏览找到包含采用适当的图形映射格式的映射规则的文件。

借助 API,使用 CreateReplicationTask API 调用的 TaskData 请求参数指定这些选项。将 TaskData 设置为包含采用适当图形映射格式的映射规则的文件的路径。

用于通过 Gremlin 生成属性图形数据的图形映射规则

使用 Gremlin 生成属性图形数据,为要从源数据生成的每个图形实体指定一个具有映射规则的 JSON 对象。此 JSON 的格式是专门为批量加载 Amazon Neptune 定义的。以下模板显示了此对象中的各个规则的情况。

{ "rules": [ { "rule_id": "(an identifier for this rule)", "rule_name": "(a name for this rule)", "table_name": "(the name of the table or view being loaded)", "vertex_definitions": [ { "vertex_id_template": "{col1}", "vertex_label": "(the vertex to create)", "vertex_definition_id": "(an identifier for this vertex)", "vertex_properties": [ { "property_name": "(name of the property)", "property_value_template": "{col2} or text", "property_value_type": "(data type of the property)" } ] } ] }, { "rule_id": "(an identifier for this rule)", "rule_name": "(a name for this rule)", "table_name": "(the name of the table or view being loaded)", "edge_definitions": [ { "from_vertex": { "vertex_id_template": "{col1}", "vertex_definition_id": "(an identifier for the vertex referenced above)" }, "to_vertex": { "vertex_id_template": "{col3}", "vertex_definition_id": "(an identifier for the vertex referenced above)" }, "edge_id_template": { "label": "(the edge label to add)", "template": "{col1}_{col3}" }, "edge_properties":[ { "property_name": "(the property to add)", "property_value_template": "{col4} or text", "property_value_type": "(data type like String, int, double)" } ] } ] } ] }

存在顶点标签意味着在此处创建了顶点。没有顶点标签意味着顶点是由其他源创建的,并且此定义仅添加顶点属性。指定所需数量的顶点和边定义,以便指定整个关系数据库源的映射。

employee 表的示例规则如下所示。

{ "rules": [ { "rule_id": "1", "rule_name": "vertex_mapping_rule_from_nodes", "table_name": "nodes", "vertex_definitions": [ { "vertex_id_template": "{emp_id}", "vertex_label": "employee", "vertex_definition_id": "1", "vertex_properties": [ { "property_name": "name", "property_value_template": "{emp_name}", "property_value_type": "String" } ] } ] }, { "rule_id": "2", "rule_name": "edge_mapping_rule_from_emp", "table_name": "nodes", "edge_definitions": [ { "from_vertex": { "vertex_id_template": "{emp_id}", "vertex_definition_id": "1" }, "to_vertex": { "vertex_id_template": "{mgr_id}", "vertex_definition_id": "1" }, "edge_id_template": { "label": "reportsTo", "template": "{emp_id}_{mgr_id}" }, "edge_properties":[ { "property_name": "team", "property_value_template": "{team}", "property_value_type": "String" } ] } ] } ] }

在此处,顶点和边定义映射来自具有员工 ID (EmpID) 的 employee 节点和具有经理 ID (managerId) 的 employee 节点的报告关系。

有关使用 Gremlin JSON 创建图形映射规则的更多信息,请参阅《Amazon Neptune 用户指南》中的 Gremlin 加载数据格式

用于生成 RDF/SPARQL 数据的图形映射规则

如果要加载将使用 SPARQL 查询的 RDF 数据,请使用 R2RML 编写图形映射规则。R2RML 是用于将关系数据映射到 RDF 的标准 W3C 语言。在 R2RML 文件中,三重映射(例如,下面的 <#TriplesMap1>)指定用于将逻辑表的每个行转换为零个或更多 RDF 三元组的规则。主题映射(例如,下面的任意 rr:subjectMap)指定了一个规则,用于生成由三元组映射生成的 RDF 三元组的主题。谓词-对象映射(例如,下面的任意 rr:predicateObjectMap)是一个函数,用于为逻辑表的每个逻辑表行创建一个或多个谓词-对象对。

下面是 nodes 表的简单示例。

@prefix rr: <http://www.w3.org/ns/r2rml#>. @prefix ex: <http://example.com/ns#>. <#TriplesMap1> rr:logicalTable [ rr:tableName "nodes" ]; rr:subjectMap [ rr:template "http://data.example.com/employee/{id}"; rr:class ex:Employee; ]; rr:predicateObjectMap [ rr:predicate ex:name; rr:objectMap [ rr:column "label" ]; ]

在上一个示例中,映射定义了从员工表映射的图形节点。

下面是 Student 表的另一个简单示例。

@prefix rr: <http://www.w3.org/ns/r2rml#>. @prefix ex: <http://example.com/#>. @prefix foaf: <http://xmlns.com/foaf/0.1/>. @prefix xsd: <http://www.w3.org/2001/XMLSchema#>. <#TriplesMap2> rr:logicalTable [ rr:tableName "Student" ]; rr:subjectMap [ rr:template "http://example.com/{ID}{Name}"; rr:class foaf:Person ]; rr:predicateObjectMap [ rr:predicate ex:id ; rr:objectMap [ rr:column "ID"; rr:datatype xsd:integer ] ]; rr:predicateObjectMap [ rr:predicate foaf:name ; rr:objectMap [ rr:column "Name" ] ].

在上一个示例中,映射定义 Student 表中人员之间的图形节点映射朋友关系。

有关使用 SPARQL R2RML 创建图形映射规则的更多信息,请参阅 W3C 规范 R2RML:RDB 到 RDF 映射语言

用于将 Gremlin 和 R2RML 迁移到作为目标的 Amazon Neptune 的数据类型

AWS DMS 通过两种方式之一执行从 SQL 源端点到 Neptune 目标的数据类型映射。所使用的方式取决于您用来加载 Neptune 数据库的图形映射格式:

  • Apache TinkerPop Gremlin,使用迁移数据的 JSON 表示形式。

  • W3C 的 SPARQL,使用迁移数据的 R2RML 表示形式。

有关这两种图形映射格式的更多信息,请参阅将 Amazon Neptune 作为目标使用时使用 Gremlin 和 R2RML 指定图形映射规则

在下文中,您可以找到每种格式的数据类型映射的描述。

SQL 源到 Gremlin 目标数据类型映射

下表显示了从 SQL 源到 Gremlin 格式化目标的数据类型映射。

AWS DMS 将任何未列出的 SQL 源数据类型映射到 Gremlin String

SQL 源数据类型

Gremlin 目标数据类型

NUMERIC(和变体) Double
DECIMAL
TINYINT Byte
SMALLINT Short
INT, INTEGER Int
BIGINT Long
FLOAT Float
DOUBLE PRECISION
REAL Double
BIT Boolean
BOOLEAN
DATE Date
TIME
TIMESTAMP
CHARACTER(和变体) String

有关用于加载 Neptune 的 Gremlin 数据类型的更多信息,请参阅《Neptune 用户指南》中的 Gremlin 数据类型

SQL 源到 R2RML (RDF) 目标数据类型映射

下表显示了从 SQL 源到 R2RML 格式化目标的数据类型映射。

所有列出的 RDF 数据类型都区分大小写,但 RDF 文本除外。AWS DMS 将任何未列出的 SQL 源数据类型映射到 RDF 文本。

RDF 文本 是多种文本词汇形式和数据类型之一。有关更多信息,请参阅 W3C 规范《资源描述框架 (RDF):概念和抽象语法》中的 RDF 文字

SQL 源数据类型

R2RML (RDF) 目标数据类型

BINARY(和变体) xsd:hexBinary
NUMERIC(和变体) xsd:decimal
DECIMAL
TINYINT xsd:integer
SMALLINT
INT, INTEGER
BIGINT
FLOAT xsd:double
DOUBLE PRECISION
REAL
BIT xsd:boolean
BOOLEAN
DATE xsd:date
TIME xsd:time
TIMESTAMP xsd:dateTime
CHARACTER(和变体) RDF 文本

有关用于加载 Neptune 的 RDF 数据类型及其与 SQL 源数据类型的映射的更多信息,请参阅 W3C 规范《R2RML:RDB 到 RDF 映射语言》中的数据类型转换

将 Amazon Neptune 作为目标的限制

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

  • AWS DMS 当前仅支持迁移到 Neptune 目标的完全加载任务。不支持将更改数据捕获 (CDC) 迁移到 Neptune 目标。

  • 在开始迁移任务之前,请确保已手动清除目标 Neptune 数据库中的所有数据,如以下示例所示。

    要删除图形中的所有数据(顶点和边),请运行以下 Gremlin 命令。

    gremlin> g.V().drop().iterate()

    要删除具有标签 'customer' 的顶点,请运行以下 Gremlin 命令。

    gremlin> g.V().hasLabel('customer').drop()
    注意

    删除大型数据集可能需要花费一些时间。您可能需要对 drop() 进行迭代并施加一个限制,例如 limit(1000)

    要删除具有标签 'rated' 的边,请运行以下 Gremlin 命令。

    gremlin> g.E().hasLabel('rated').drop()
    注意

    删除大型数据集可能需要花费一些时间。您可能需要对 drop() 进行迭代并施加一个限制,例如 limit(1000)

  • 由于 Neptune 图形数据结构的性质,DMS API 操作 DescribeTableStatistics 可能会返回有关给定表的不准确结果。

    在迁移过程中,AWS DMS 会扫描每个源表,并使用图形映射将源数据转换为 Neptune 图形。转换后的数据首先会存储在为目标终端节点指定的 S3 存储桶文件夹中。如果已扫描源并成功生成此中间 S3 数据,则 DescribeTableStatistics 会假定已成功将数据加载到 Neptune 目标数据库中。但情况并非总是如此。要是否已为给定表正确加载数据,请比较该表的迁移两端的 count() 返回值。

    在以下示例中,AWS DMS 已从源数据库加载 customer 表,该表在目标 Neptune 数据库图形中分配有标签 'customer'。您可以确保此标签已写入到目标数据库中。为此,请将源数据库中可用的 customer 行数与任务完成后在 Neptune 目标数据库中加载的带 'customer' 标签的行数进行比较。

    要使用 SQL 获取源数据库中可用的客户行的数量,请运行以下命令。

    select count(*) from customer;

    要使用 Gremlin 获取加载到目标数据库图形中的带 'customer' 标签的行数,请运行以下命令。

    gremlin> g.V().hasLabel('customer').count()
  • 目前,如果任一表无法加载,则整个任务将失败。与关系数据库目标不同,Neptune 中的数据是高度互连的,这导致在许多情况下无法恢复任务。如果因无法加载此类型的数据而导致无法成功恢复任务,请创建一个新任务来加载未能加载的表。在运行此新任务之前,请从 Neptune 目标中手动清除部分已加载的表。

    注意

    如果故障可恢复(例如,网络传输错误),则可以恢复已失败的迁移到 Neptune 目标的任务。

  • AWS DMS 支持大多数适用于 R2RML 的标准。但是,AWS DMS 不支持某些 R2RML 标准,包括反向表达式、联接和视图。R2RML 视图的解决方法是,在源数据库中创建相应的自定义 SQL 视图。在迁移任务中,使用表映射选择视图作为输入。然后将视图映射到一个表,R2RML 随后会使用该表来生成图形数据。

  • 在使用不受支持的 SQL 数据类型迁移源数据时,生成的目标数据可能会丢失精确性。有关更多信息,请参阅用于将 Gremlin 和 R2RML 迁移到作为目标的 Amazon Neptune 的数据类型

  • AWS DMS 不支持将 LOB 数据迁移到 Neptune 目标中。