亚马逊AWS官方博客

利用离线方案实现从 MongoDB 到 Amazon DocumentDB 的迁移

Original URL: https://amazonaws-china.com/cn/blogs/database/migrate-from-mongodb-to-amazon-documentdb-using-the-offline-method/

Amazon DocumentDB(兼容MongoDB)是一项快速、可扩展且可用性高的全托管文档数据库服务,能够全面支持MongoDB工作负载。

Amazon DocumentDB文档中介绍三种从MongoDB向Amazon DocumentDB迁移的主要方法,分别为:离线、在线与混合。

离线迁移方法在其中拥有最快的速度与最低的操作门槛,但同时也会带来最长的停机时间。离线迁移最适合匹配概念验证、开发与测试类工作负载,以及那些对停机时间不太敏感的生产级工作负载。作为DocumentDB迁移三篇系列文章中的第一篇,我们将在本文中尝试使用离线方法将数据从Amazon EC2上的MongoDB副本集迁移至Amazon DocumentDB集群。

离线迁移概述

下图所示,为从MongoDB到Amazon DocumentDB的整个离线迁移流程。

整个迁移方案包含五个基本步骤:

  1. 停止应用程序向源MongoDB部署的写入操作。
  2. 使用mongodump工具将索引与数据转储至EC2实例。
  3. (可选)使用Amazon DocumentDB索引工具将索引还原至Amazon DocumentDB集群。
  4. 使用mongorestore工具将数据还原至Amazon DocumentDB集群。
  5. 变更应用程序中的连接字符串,将其指向新的Amazon DocumentDB集群。

迁移前的准备工作

要执行离线迁移,我们需要以下三个组件:

  1. 一套部署完成的源MongoDB
  2. 一个用于数据导出与导入的EC2实例
  3. 一个目标Amazon DocumentDB集群

在迁移至Amazon DocumentDB集群之前,我们首先要叫停应用程序对源MongoDB部署的写入操作。只有这样,我们才能保证在迁移至Amazon DocumentDB集群期间,源内的数据不再发生变化。源MongoDB部署为部署在Amazon EC2上的副本集。为了尽可能降低工作负载迁移对这一副本集的影响,这里我们从辅助实例处导出数据。

如果您的MongoDB源使用的MongoDB版本低于3.6,则应首先升级源部署及应用驱动程序。只有将版本升级至MongoDB 3.6或更高,才能实现面向Amazon DocumentDB的正常迁移。

您可以在mongo shell当中输入以下代码以确定源部署的当前版本:

rs0:PRIMARY> db.version()
3.6.9

使用Amazon DocumentDB控制台,我们创建一个作为迁移目标的新Amazon DocumentDB集群,如下图所示:

数据还原所需要的时间,在一定程度上取决于目标集群上的主实例大小。为了尽可能提高导入吞吐量,我们在示例中创建一个r4.16xlarge实例,这也是AWS区域当中Amazon DocumentDB所能支持的最高配置选项。虽然这里也可以使用相对较低的实例配置,但数据导入时间有可能因此延长。在数据迁移完成之后,您可以根据需要再次调整主实例的具体大小。接下来,我们即可添加额外的只读副本以实现读取扩展与高可用性。

最后一个组件则是EC2实例,我们要利用它运行导出与导入进程(即迁移实例)。对迁移实例的一大基本要求,就是其Amazon EBS存储卷必须足以容纳导出的数据总量。您可以在mongo shell当中运行db.stats()命令并查看storageSize的值以粗略估算待迁移数据库的大小(单位为字节)。

除了mongo shell之外,迁移实例还需要用到mongodump与mongorestore两款工具。因此,我们至少需要安装mongodb-org-shell与mongodb-org-tools两个工具包。(更多细节信息,请参阅MongoDB说明文档。)

由于Amazon DocumentDB在默认情况下使用传输层安全(TLS)协议进行加密,因此我们还必须下载Amazon RDS证书颁发机构(CA)文件才能通过mongo shell建立连接:

[ec2 ]$ curl -O https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem

(您也可以直接禁用TLS。若需了解更多细节信息,请参阅〈Amazon DocumentDB开发者指南〉中的使用TLS加密连接部分。)

在shell与工具安装完成后,我们需要确保迁移实例能够与源实例以及目标Amazon DocumentDB集群进行正常通信。要执行验证,我们需要按以下方法接入二者并运行ping命令。

接入源副本集实例:

[ec2]$ mongo --host my-secondary-hostname \
--username myuser --password mypassword
…
rs0:PRIMARY> db.runCommand('ping')
{ "ok" : 1 }

接入Amazon DocumentDB集群:

[ec2]$ mongo --ssl --host docdb-cluster-endpoint \
--sslCAFile rds-combined-ca-bundle.pem --username myuser \
--password mypassword
…
rs0:PRIMARY> db.runCommand('ping')
{ "ok" : 1 }

如果无法接入源实例或者Amazon DocumentDB集群,则需要检查二者的安全组配置,确保EC2实例有权在正确的端口(默认为端口27017)上接入各安全组。关于故障排查的更多细节信息,请参阅对Amazon DocumentDB进行故障排查

使用mongodump进行数据转储

建立连接之后,现在我们可以使用mongodump工具将数据及索引导出至目标EC2迁移实例。在这里,我们将–-readPreference选项设置为secondary,相当于强调将转储连接指向辅助副本集中的成员。这步操作可减少mongodump操作对源部署造成的潜在影响。要使用–-readPreference选项,我们需要首先通过replicaSetName/replicasetMember的形式接入该副本集成员:

[ec2]$ mongodump --host rs0/myhost --username user \
--password password --db books --authenticationDatabase admin \
--readPreference secondary
2019-03-19T00:16:57.095+0000	writing books.j to
2019-03-19T00:16:57.095+0000	writing books.a to
2019-03-19T00:16:57.424+0000	done dumping books.j (100000 documents)
2019-03-19T00:16:57.445+0000	done dumping books.a (100000 documents)

数据导出的具体时长取决于源数据集的大小、迁移实例与源部署之间的网络传输速度,以及迁移实例的资源配置水平。

使用Amazon DocumentDB索引工具还原索引

虽然在离线迁移场景下并非必要,但我们仍可利用Amazon DocumentDB索引工具检索转储完成后索引的兼容性,并在目标Amazon DocumentDB集群之上预创建对应索引。这种预创建索引操作能够显著缩短整个还原时间,因为还原过程实际上相当于并行填充操作,而非由mongorestore执行的索引按序还原操作。

您可以直接从Amazon DocumentDB工具GitHub repo处克隆该工具,并按照README.md中的指示分步操作。

在Amazon DocumentDB索引工具安装完成之后,我们即可利用它验证索引定义中是否存在兼容性问题:

[ec2]$ python migrationtools/documentdb_index_tool.py –-show-issues –-dir <dump_dir>

现在,我们可以利用索引工具在目标Amazon DocumentDB集群上创建索引了:

[ec2]$ python migrationtools/documentdb_index_tool.py –-restore-indexes –-dir <dump_dir> --host docdb-cluster-endpoint –-tls –-tls-ca-file rds-combined-ca-bundle.pem --username myuser --password mypassword

使用mongorestore将数据还原至集群

在索引预创建完成后,我们将使用mongorestore工具将导出的数据还原至目标Amazon DocumentDB集群。在这一步,我们可以使用mongorestore通过–-numInsertionWorkersPerCollection选项实现并发导入。作为良好的起点,大家最好将该选项设置为Amazon DocumentDB集群主实例上的实际vCPU数量。由于示例中使用的集群主实例大小为r4.16xlarge,因此包含64个vCPU,可以设置的最大值同样为64。由于我们之前已经使用Amazon DocumentDB索引工具完成了索引的预创建,因此这里可以直接跳过–-noIndexRestore选项——毕竟我们没必要重复创建索引:

[ec2]$ mongorestore --host docdb-cluster-endpoint –-ssl –-sslCAFile rds-combined-ca-bundle.pem --username myuser --password mypassword – numInsertionWorkersPerCollection 64 --noIndexRestore <dump_dir>

注意:如果我们执行了完整的mongodump操作(即没有使用--db选项以指定需要转储的数据库),那么这里需要删除转储目录当中的admin目录。否则,我们会在还原至Amazon DocumentDB时发生错误。

指向Amazon DOcumentDB集群

在数据还原完成之后,接下来即可变更应用程序中的数据库连接字符串以使用新建的Amazon DocumentDB集群了。关于更多细节信息,请参阅《Amazon DocumentDB开发者指南》中的Amazon DocumentDB端点使用指南

总结

在本系列文章中的第一篇里,我们介绍了将数据从MongoDB离线迁移至Amazon DocumentDB的基本操作步骤。您可以在《Amazon DocumentDB迁移指南》当中找到关于其他迁移方法的更多信息,以及在迁移至Amazon DocumentDB时需要重视的注意事项。

如果您对本文有任何疑问或者建议,请在下方评论中分享您的观点。


本篇作者

Jeff Duffy

Amazon Web Services公司NoSQL专业高级经理,专注于Amazon DocumentDB相关事务。