MongoDB 云上数据迁移之纯手工操作实用教程

我们为用户提供 MongoDB 服务的过程中,发现很多用户都有在云服务商之间迁移数据的需求。在没有专业迁移工具的时候,如何实现数据库跨云迁移?今天我们就分享下利用开源工具进行纯手工操作 MongoDB 数据库迁移的方案。

 

本方案基于 MongoDB  3.2.7 版本进行讨论,迁移目标数据库为华为云DDS数据库,源库为自建或其他云服务商MongoDB 数据库。

 

注意:本篇文章涉及的迁移方案是特定场景下的一种方案,有其局限性。当迁移的数据库是分片集群模式时,若使用mongodump,mongorestore迁移完成后由于分片名字在各个云服务商命名是不一样的并且云服务商存在各种安全策略,迁移困难且迁移完成后是无法使用的。因此本篇文章使用了mongoexport,mongoimport来做迁移,这一对工具由于对一些复杂的 BSON 类型无法全部表示,因此当源库数据类型很丰富可能会导致迁移后的数据类型精度降低,建议酌情使用。如果是副本集迁移建议使用 mongodump,mongorestore,后续会有相应的文章进行描述。

 

任何方案都是有业务场景,不同业务场景对应方案的操作和复杂度不一样,因此我们按照业务场景的复杂度讲解。

业务数据不重要,允许业务长时间中断型

 

  1. 停掉正在使用的 MongoDB 服务,中断业务,不允许任何数据变更。
  2. 使用 mongoexport 导出数据

mongoexport --host <DB_ADDRESS> --port <DB_PORT> --ssl --sslAllowInvalidCertificates --type json --authenticationDatabase <AUTH_DB> --username <DB_USER> --password <DB_PASSWORD> --db <DB_NAME> --collection <DB_COLLECTION> --out <DB_PATH>

  1. 使用 mongoimport 将数据导入到华为云 DDS

     mongoimport --host <DB_ADDRESS> --port <DB_PORT> --ssl --sslAllowInvalidCertificates --type json --authenticationDatabase <AUTH_DB> --username <DB_USER> --password <DB_PASSWORD> --db <DB_NAME> --collection <DB_COLLECTION> --file <DB_PATH>

    注意:如果购买的华为云数据库有公网 IP,可以在任何一台能连上公网IP的服务器上导入导出数据。如果没有购买公网 IP,则先购买一台华为云的 ECS,这台ECS和数据库在同一个网段和安全组,然后在这台ECS上导入数据。

  1. 将业务数据库 IP 切换至华为云 MongoDB,启动业务,数据迁移成功。

业务数据不重要,允许丢失数据但不能中断业务型

此业务场景一般客户数据为临时,但业务不能中断,必须保证在迁移时间段业务可用。第二个业务场景和第一个很相似,因此迁移数据的方案也很相似:

 

在数据迁移阶段不暂停正在使用的数据库,数据迁移完成直接切换数据库 IP 到华为云DDS。由于没有从原数据库同步数据到华为云DDS,迁移时间段内发生的业务数据会丢失。

 

业务数据重要不允许丢失,业务不允许中断型

 

此业务场景中我们选取最具代表性也最复杂的场景进行分析:选取用户存量数据大(T 级数据),OPS 高,一个小时就新增上百 G 数据。因为存量数据大,数据迁移至少在数小时以上, OPS 高,那么在迁移时间段会积累上百 G 数据没有迁移到华为 DDS。

 

MongoDB 社区版没有提供增量导出、增量备份数据的方案,这些功能都是企业版 MongoDB 才提供的。那么我们能用纯手工的方式(使用 MongoDB 开源社区提供的生态工具)做到增量迁移数据吗?

 

答案是利用开源工具是无法完美做到纯手工增量迁移的。原因如下:

  1. mongoexport/mongoimport :

 

首先说下 mongoexport 的工作原理。如上图所示:当我们一边用 mongoexport 导出数据,一边往数据库里插入数据时,显然最后导出的数据大于开始执行 mongexport 时数据库的数据。

 

看了下 mongoexport 的源码,工作流程大概如下:

 

  1. 首先获取开始执行 mongoexport 导出数据库的记录数量。
  2. 得出记录数量后,mongoexport 开启一个 cursor,利用 cursor 迭代读取数据,cursor 每次读取都是批量读取,最后一次迭代读取的数据量是在此时数据库总量和每次批量读取数据量中取最大值。
  3. 如果此时数据库一直在变更数据,那么很难确定最后总共读取的数量。意味着当用户在导出数据过程中一直在变更数据,则使用 mongoexport 导出的总数据量无法确定。

 

那么迁移过程中新增数据怎么增量迁移呢?mongoexport 本身并没有提供增量迁移的功能,但可以通过回放 Oplog 的方法,将迁移过程中增量数据的 Oplog 在目标机器上进行重做。

 

由于 Oplog 记录的是所有数据,当然也包括不是这次迁移需要的数据的 Oplog,因此对Oplog 进行过滤重放,手工处理比较麻烦也容易出错,需要写程序进行自动处理。

 

  1. mongodump/mongorestore:

 

mongodump 可以备份所有数据,然后利用 mongrestore 进行恢复。对于备份过程中的增量数据,可以使用开源工具 mongooplog 处理增量 Oplog 以达到增量备份数据的目的。

 

但由于不同云服务商对 Shard 的命名各不相同,因此恢复完成后必须登录数据库手动修改数据库里面 Shard 的名字,这一步手动处理比较麻烦也容易出错。这种工具主要用在副本集之间的迁移。

 

上述两种方法都需要注意 Oplog 的大小,防止在备份过程中新增数据量过大,Oplog数据被轮转覆盖,一旦覆盖就无法增量备份数据了。

 

总结

目前纯手工操作的迁移数据方式只能适应一些比较简单的业务场景,对于复杂场景,手工迁移存在操作复杂容易出错的缺点。

 

程序化自动化的 MongoDB 迁移工具不久就会出现在华为云官网上,它将是用户最贴心的解决方案。

 

PS:华为云数据库免费迁移 “零”中断上云活动火热进行中,配套 MongoDB 等多款数据库 1 元 30 天超长体验。扫描下方二维码,立即体验:

 

 

猜你喜欢

转载自blog.csdn.net/shijin23/article/details/81070569