【OCI クラウド移行ガイド】NoSQL Database MigratorでAmazon DocumentDB を Oracle NoSQL Database Cloud Serviceへ移行してみた

# OCIクラウド移行ガイドとは

オンプレミスやAWSなど、複数のプラットフォームからOracle Cloud Infrastructureへの移行プロジェクトに取り組んでいるクラウドエンジニア（@araidon,@kazunishi,@yama6）による、OCI移行手順をまとめたシリーズ記事です。
各回、サンプルワークロードから対象サービスを取り上げ、移行手順をガイドいたします。

# 移行したいサンプルワークロード

日々の業務でよく目にするサービスを中心に、サンプルワークロードとしてまとめてみました。このシリーズでは、主にAWSからの移行を取り上げます。
このワークロードは、ユーザがログインして、Web上で写真を共有するWebサービスをイメージしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325706/1c9074f1-d4df-e201-1274-0b92d49837e1.png)

# 移行するサービス：Amazon DocumentDB

今回、移行対象とするのはAmazon DocumentDBです。
Amazon DocumentDBはMongoDB互換のルマネージド型のネイティブ JSON ドキュメントデータベースです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325706/443baf5c-d790-230c-ab4d-3bb1e10fe739.png)

Oracle NoSQL Database Migratorを利用した移行手順をガイドします。


# NoSQL Database Migratorとは

OCIにもOracle NoSQL Database Cloud ServiceというNoSQL Databaseサービスがあり、Amazon DynamoDBやMongoDB等のkey-value型DBからの移行をサポートするNoSQL Database Migratorというツールが用意されてます。

>Oracle NoSQL Database Migratorを使用して、NoSQL表をあるデータ・ソースから別のデータ・ソース(オンプレミスまたはクラウドのOracle NoSQL Databaseなど)または単純なJSONファイルに移動できます。MongoDB形式のJSON入力ファイル、DynamoDB形式のJSON入力ファイル(AWS S3ソースまたはファイルから格納)またはCSVファイルをオンプレミスまたはクラウドのNoSQLデータベースにコピーすることもできます。

https://docs.public.oneportal.content.oci.oraclecloud.com/ja-jp/iaas/nosql-database/doc/overview.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325706/3d2f1800-d7d8-53ae-7ad7-f0ddab4353b9.png)


# 移行方式

NoSQL Database Migratorでは、移行元を"ソース"、移行先を"シンク"と表現します。
今回は、下記を移行元、移行先とした場合のガイドをご案内します。

|移行元（ソース） |移行先（シンク）
|---|---
|MongoDB形式のJSONファイル|Oracle NoSQL Database Cloud Service

NoSQL Database MigratorがインストールされているEC2のストレージに格納されたMongoDB形式のJSONファイルをソースとして、Oracle NoSQL Database Cloud Serviceへデータを移行します。
データの移行だけではなく、ツールの実行過程で移行先（シンク）であるOracle NoSQL Database Cloud Serviceも構築することができます。
大枠の流れとしては、下記リファレンスを参考にして移行ガイドを作成しました。

https://docs.oracle.com/cd/F79106_01/admin/migrate-mongodb-json-file-oracle-nosql-database-cloud-service.html#GUID-F25D53D3-E000-4F97-A8B5-1D5228E428A3

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325706/896b371d-bd6e-7c7f-3ea4-ab9857cc65ff.png)

# 前提条件

本記事のガイドに沿って移行を実施する前提条件は、２つです。
1. 下記記事を参考に、Amazon EC2にOracle NoSQL Database Migratorがインストールされ、実行できる状態であること。

https://qiita.com/yama6/items/346bea6e7f06d3f19116

:::note warn
上記の記事では、Amazon Linux2023を接続用インスタンスとして記事を書いていますが、DocumentDBの最新バージョン5.0.0に合わせてMongoDB 5.0のインストールを実行したところ、うまくいかなかったため、この記事では、接続用インスタンスにAmazon Linux2を利用しています。
:::

2.Oracle NoSQL Database MigratorがインストールされているEC2に紐づけられたIAM RoleへAmazon DocumentDBを操作するためのIAM Policyが付与されていること。
※追加方法は下記記事を参考にしてください。

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_access-keys.html#Using_CreateAccessKey

# 移行手順
1. Amazon DocumentDB作成
2. mongoexportでMongoDB形式のJSONファイルエクスポート
3. NoSQL Database Migrator実行
4. 実行結果の確認

# 1. Amazon DocumentDB作成
まずは、移行元となるAmazon DocumentDBを作成していきます。
# 1-1. Amazon DocumentDB用のセキュリティグループ作成
DocumentDBを作成するにあたり、セキュリティグループが必要となってくるため、こちらを作成します。
VPCからセキュリティグループを選択し、作成ボタンを押下します。
セキュリティグループ名を入れ、DocumentDBに接続するためのEC2が存在するVPCを選択します。
その後、インバウンドルールを下記のように設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325706/d2b13007-366f-807c-1d46-40e04e02ef27.png)
ポート範囲はmongoDBのプロトコル番号となる27017を入力します。
ソースに、接続用のEC2が使用しているセキュリティグループを選択します。
これで、このあと作成するDocumentDBは、接続用のEC2からのみ、ポート番号27017で接続できるようになります。

# 1-2. Amazon DocumentDBの作成
次に、DocumentDBを作成していきます。
Amazon DocumentDBの画面に遷移し、Createボタンを押下します。
作成画面遷移後、下記の内容を参考に入力し、Create clusterボタンを押下してください。

|パラメータ |設定内容
|---|---
|Cluster type|Instance Based Cluster
|Configuration|
|Cluster identifier|test-docdb（任意）
|Engine version|5.0.0
|Instance class|db.t4g.meduim
|Number of instances|1
|Authentication|
|Username|(任意：admin以外)
|Password |任意
|Show advanced settings|押下
|Network settings|
|Virtual Private Cloud (VPC) |接続用のEC2が存在するVPCを選択
|Virtual Private Cloud (VPC) |デフォルトを選択
|VPC security groups|1-1で作成したセキュリティグループを選択
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325706/91465789-3eca-a091-02c2-0fdcc2b28149.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325706/ab9a61ff-21c0-e9ca-0f41-aec5efed7357.png)

作成ボタン押下後、十数分で作成が完了します。

# 1-3. MongoDB Community Edition 5.0のインストール
DocumetDBを操作するため、mongoshellを接続用インスタンスにインストールします。
先述した通り、接続用インスタンスには、Amazon Linux2を利用しています。
インストール方法は下記の記事を参考にしました。

https://www.mongodb.com/docs/v5.0/tutorial/install-mongodb-on-amazon/

# 1-3-1. パッケージ管理システムの構成
```
$ sudo vi /etc/yum.repos.d/mongodb-org-5.0.repo
```
# 1-3-2. ファイルの編集
```
[mongodb-org-5.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/amazon/2/mongodb-org/5.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-5.0.asc
```
# 1-3-3. インストールの実行
```
$ sudo yum install -y mongodb-org-5.0.20 mongodb-org-database-5.0.20 mongodb-org-server-5.0.20 mongodb-org-shell-5.0.20 mongodb-org-mongos-5.0.20 mongodb-org-tools-5.0.20
```
# 1-3-4. バージョンの確認
```
$ mongo -version
MongoDB shell version v5.0.20
Build Info: {
    "version": "5.0.20",
    "gitVersion": "2cd626d8148120319d7dca5824e760fe220cb0de",
    "openSSLVersion": "OpenSSL 1.0.2k-fips  26 Jan 2017",
    "modules": [],
    "allocator": "tcmalloc",
    "environment": {
        "distmod": "amazon2",
        "distarch": "x86_64",
        "target_arch": "x86_64"
    }
}
```

# 1-4. mongoshellによるAmazon DocumentDBへの接続
1-2で作成したDocumentDBのクラスターを選択し、Connectのフィールドを参照します。

このうち、"Download the Amazon DocumentDB Certificate Authority (CA) certificate required to authenticate to your cluster" と "Connect to this cluster with the mongo shell"を実行し、mongoshellからDocumentDBに接続します。

Download the Amazon DocumentDB Certificate Authority (CA) certificate required to authenticate to your cluster
```
wget https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem
```

Connect to this cluster with the mongo shell
```
mongo --ssl --host test-docdb.cluster-XXXXXXXXXX.ap-northeast-1.docdb.amazonaws.com:27017 --sslCAFile global-bundle.pem --username 1-2で入力したユーザ名 --password 1-2で入力したパスワード
```
実行結果
```
{"t":{"$date":"2023-11-05T09:46:57.473Z"},"s":"W",  "c":"CONTROL",  "id":23321,   "ctx":"-","msg":"Option: This name is deprecated. Please use the preferred name instead.","attr":{"deprecatedName":"ssl","preferredName":"tls"}}
{"t":{"$date":"2023-11-05T09:46:57.473Z"},"s":"W",  "c":"CONTROL",  "id":23321,   "ctx":"-","msg":"Option: This name is deprecated. Please use the preferred name instead.","attr":{"deprecatedName":"sslCAFile","preferredName":"tlsCAFile"}}
MongoDB shell version v5.0.20
connecting to: mongodb://test-docdb.cluster-XXXXXXXXXX.ap-northeast-1.docdb.amazonaws.com:27017/?compressors=disabled&gssapiServiceName=mongodb
{"t":{"$date":"2023-11-05T09:46:57.623Z"},"s":"I",  "c":"NETWORK",  "id":5490002, "ctx":"thread4","msg":"Started a new thread for the timer service"}
Implicit session: session { "id" : UUID("21a37675-4125-4626-9e49-7b97d9a8790a") }
MongoDB server version: 5.0.0
================
Warning: the "mongo" shell has been superseded by "mongosh",
which delivers improved usability and compatibility.The "mongo" shell has been deprecated and will be removed in
an upcoming release.
For installation instructions, see
https://docs.mongodb.com/mongodb-shell/install/
================

Warning: Non-Genuine MongoDB Detected

This server or service appears to be an emulation of MongoDB rather than an official MongoDB product.

Some documented MongoDB features may work differently, be entirely missing or incomplete, or have unexpected performance characteristics.

To learn more please visit: https://dochub.mongodb.org/core/non-genuine-mongodb-server-warning.
rs0:PRIMARY> 

```
これで接続用のEC2からDocumentDBへ接続を確認できました。

# 1-5. mongoimportによるデータインポート
DocumentDBにデータをインポートしていきます。
今回は、接続用のEC2からmongoimportユーティリティを使用して、サンプルデータをインポートします。
実行には下記記事を参考にしました。

https://docs.aws.amazon.com/ja_jp/documentdb/latest/developerguide/backup_restore-dump_restore_import_export_data.html#backup_restore-dump_restore_import_export_data-mongoimport

まず、DocunemtDBから抜けてEC2に戻ります。
```
rs0:PRIMARY> exit
bye
$
```
サンプルデータをダウンロードします。
```
wget https://raw.githubusercontent.com/ozlerhakan/mongodb-json-files/master/datasets/restaurant.json
```
このjsonファイルのデータをDocumentDBにダウンロードします。
先ほど紹介した記事の「3.Amazon DocumentDB にサンプルデータをインポートする」ではうまくいかないので、1-4で参照したConnectの"Connect to this cluster with an application"を参考にしてコマンドを実行します。
```
mongoimport --uri="mongodb://ユーザ名:パスワード@test-docdb.cluster-XXXXXXXXXX.ap-northeast-1.docdb.amazonaws.com:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false" --collection=restaurants --db=business --file=restaurant.json
```
これで、restaurants というコレクションにbusinessというデータベースが作成され、restaurant.jsonのデータが2,548行インポートされます。

```
2023-11-05T10:26:08.105+0000    connected to: mongodb://[**REDACTED**]@test-docdb.cluster-cn07mhl9cm4v.ap-northeast-1.docdb.amazonaws.com:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false
2023-11-05T10:26:08.354+0000    2548 document(s) imported successfully. 0 document(s) failed to import.
```

再度mongoshellからDocumentDBに接続し、データがインポートされたか確認します。
```
mongo --ssl --host test-docdb.cluster-XXXXXXXXXX.ap-northeast-1.docdb.amazonaws.com:27017 --sslCAFile global-bundle.pem --username 1-2で入力したユーザ名 --password 1-2で入力したパスワード
rs0:PRIMARY> use business
switched to db business
rs0:PRIMARY> db.restaurants.find().count()
2548
```
先ほどインポートしたデータが2,548行確認できました。

# 2. mongoexportでMongoDB形式のJSONファイルエクスポート
ソースのMongoDB形式のJSONファイルを作成するため、今度はmongoexportユーティリティを使用してjsonデータをエクスポートします。
```
$ mongoexport --uri="mongodb://ユーザ名:パスワード@test-docdb.cluster-XXXXXXXXXX.ap-northeast-1.docdb.amazonaws.com:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false" --collection=restaurants --db=business --out=output-restaurant.json
2023-11-05T10:34:00.915+0000    connected to: mongodb://[**REDACTED**]@test-docdb.cluster-cn07mhl9cm4v.ap-northeast-1.docdb.amazonaws.com:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false
2023-11-05T10:34:01.018+0000    exported 2548 records
```
output-restaurant.jsonというファイル名で、DocumentDBから2,548行のデータがエクスポートされたことを確認できました。

# 3. NoSQL Database Migrator実行
では、このoutput-restaurant.jsonをMongoDB形式のJSONファイル（＝ソース）として、NoSQL Database Migratorを使用して Oracle NoSQL Database Cloud Service（＝シンク）に移行していきたいと思います。

まずは、移行の設定ファイルであるmigrator-config.jsonを作成します。

migrator-config.json
```
{
  "source" : {
    "type" : "file",
    "format" : "mongodb_json",
    "dataPath" : "/home/ec2-user/nosqlMigrator/nosql-migrator-1.5.0/output-restaurant.json"
  },
  "sink" : {
    "type" : "nosqldb_cloud",
    "endpoint" : "ap-tokyo-1",
    "table" : "mongoImport",
    "compartment" : "コンパートメント名",
    "schemaInfo" : {
      "defaultSchema" : true,
      "readUnits" : 100,
      "writeUnits" : 60,
      "storageSize" : 1
    },
    "credentials" : "/home/ec2-user/.oci/config",
    "credentialsProfile" : "DEFAULT",
    "writeUnitsPercent" : 90,
    "requestTimeoutMs" : 5000
  },
  "abortOnError" : true,
  "migratorVersion" : "1.5.0"
}

```
typeをファイル、formatにmongodb_jsonを指定しているところが今回の移行のポイントです。

このファイルを指定して、runMigratorを実行します。
```
$ ./runMigrator --config ./migrator-config.json 
```
実行結果はこのようになります。
```
2023-11-02 08:57:31.911 [INFO] Configuration for migration:
{
  "source" : {
    "type" : "file",
    "format" : "mongodb_json",
    "dataPath" : "/home/ec2-user/nosqlMigrator/nosql-migrator-1.5.0/output-restaurant.json"
  },
  "sink" : {
    "type" : "nosqldb_cloud",
    "endpoint" : "ap-tokyo-1",
    "table" : "mongoImport",
    "compartment" : "コンパートメント名",
    "schemaInfo" : {
      "defaultSchema" : true,
      "readUnits" : 100,
      "writeUnits" : 60,
      "storageSize" : 1
    },
    "credentials" : "/home/ec2-user/.oci/config",
    "credentialsProfile" : "DEFAULT",
    "writeUnitsPercent" : 90,
    "requestTimeoutMs" : 5000
  },
  "abortOnError" : true,
  "migratorVersion" : "1.5.0"
}
2023-11-02 08:57:31.919 [INFO] creating source from given configuration:
2023-11-02 08:57:31.921 [INFO] source creation completed
2023-11-02 08:57:31.922 [INFO] creating sink from given configuration:
2023-11-02 08:57:34.225 [INFO] sink creation completed
2023-11-02 08:57:34.228 [INFO] creating migrator pipeline
2023-11-02 08:57:34.228 [INFO] migration started
2023-11-02 08:57:34.228 [INFO] [cloud sink] : start loading DDLs
2023-11-02 08:57:34.241 [INFO] [cloud sink] : executing DDL: CREATE TABLE IF NOT EXISTS mongoImport (id STRING, document JSON, PRIMARY KEY(SHARD(id))),limits: [100, 60, 1]
2023-11-02 08:57:39.352 [INFO] [cloud sink] : completed loading DDLs
2023-11-02 08:57:39.532 [INFO] [cloud sink] : start loading records
2023-11-02 08:57:39.537 [INFO] [mongo file source] : start parsing MongoDB JSON records from file: output-restaurant.json
2023-11-02 08:58:21.453 [INFO] migration completed.
Records provided by source=2,548, Records written to sink=2,548, Records failed=0, Records skipped=0.
Elapsed time: 0min 47sec 218ms
Migration completed.
```
下記のDDL文が自動生成され、2,548行分データが移行されたことがわかります。
```
CREATE TABLE IF NOT EXISTS mongoImport (id STRING, document JSON, PRIMARY KEY(SHARD(id)))
```

# 4. 実行結果の確認
OCIにログインし、Oracle NoSQL Database Cloud Serviceの画面からmongoImportというDBが作成されているか確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325706/8dccfae2-3eb2-38df-834f-231a9e788a24.png)
DBが作成されていることが確認できました。

データの探索に、下記のSQL文を入力し、実行します。
2,548行のデータがインポートされているか確認します。

```
SELECT count(*) FROM mongoImport
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325706/fb0850ec-c1e9-e960-c92e-63a14b5c43f5.png)

2,548行のデータが確認できました！

実際にデータが格納されていることも確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325706/6e758fdf-ef95-ca0a-0d28-b7f756ccd10d.png)

# まとめ
mongodbのマネージドサービスであるAmazon DocumentDBからOracle NoSQL Database Cloud Serviceへ移行を行うことができました。これまで、NoSQL Database Migratorで移行を行ったソースとシンクをまとめました。

|サービス|ソース |シンク|記事URL
|---|---|---|---
|Amazon DynamoDB|DynamoDB JSON|Oracle NoSQL Database Cloud Service|https://qiita.com/yama6/items/346bea6e7f06d3f19116
|Amazon keyspace|csv|Oracle NoSQL Database Cloud Service|https://qiita.com/yama6/items/c7c346c721698bb8c7de
|Amazon DocumentDB|MongoDB形式のJSONファイル|Oracle NoSQL Database Cloud Service|(本記事)

AWSでは、目的型DBサービスとして複数のDBが用意されていますが、OCIでは、key-value型のNoSQL DBとして、Oracle NoSQL Database Cloud ServiceにDBを統一、統合することが可能です。
DBを統一することで、管理工数の削減や、共通インターフェース利用による開発効率の向上が見込めます。

# 参考

https://docs.oracle.com/cd/F79106_01/admin/migrate-mongodb-json-file-oracle-nosql-database-cloud-service.html#GUID-F25D53D3-E000-4F97-A8B5-1D5228E428A3

https://www.mongodb.com/docs/database-tools/mongoexport/

https://docs.aws.amazon.com/ja_jp/documentdb/latest/developerguide/backup_restore-dump_restore_import_export_data.html#backup_restore-dump_restore_import_export_data-mongoimport