MongoDB v3.2 を Amazon DocumentDB に移行したら快適になった話

こんにちは!
エージェンシー事業のシニアシステムエンジニアの遠藤です。

2023年5月頃に、私が運用/開発に携わっている広告運用システムで、 MongoDB on Amazon EC2 (以下 MongoDB )から Amazon DocumentDB (以下 DocumentDB )への移行を行いました。

本日はこの移行での取り組みについてご紹介します。

MongoDB の利用用途

当システムでは、広告のレポートデータを一定時間ごとに取得し MongoDB へ保存しています。
数年間分のデータを保存しているため、膨大な量のデータを保持していますが、
高速にデータ集計、検索処理が可能となっています。

移行の背景

この度の移行は、当システムが直面していた以下4つの課題を解決するために行われました。

1. MongoDB のバージョンが古い

当システムで使用されている MongoDB のバージョンは 3.2 で、 これは2015年12月にリリースされた古いバージョンです。
2023年7月時点では安定版はバージョン 6.0 までリリースされています。

2. 公式モニタリングツールのサポート対象外バージョン

以前、当システムでは MongoDB Cloud Manager を使用してモニタリングを行っていましたが、
古い MongoDB のバージョンによりサポート対象外となり、モニタリングが不能になってしまいました。
このため、自作の監視スクリプトで最低限の監視のみ行っていました。

3. ストレージの逼迫

MongoDB で使用しているストレージは約3TBに達し、使用可能なストレージの90%近くを占めていました。
ストレージが逼迫しているため、過去の不要なデータを定期的に削除していました。
しかし、MongoDB v3.2 の WiredTiger ストレージエンジンはデータ削除の際に空き領域がOSに解放されません。
空き領域を解放するためにデフラグコマンド compact を実行する必要があるのですが、
実行中はデータベースがロックされてしまうので容易に実行できない状況でした。

4. 9台の EC2 インスタンスのメンテナンス

EC2 で定常的に発生する作業として以下があります。

  • EC2 のメンテナンスに伴う定期的な再起動
  • Amazon Linux のアップデート
  • セキュリティアップデート

MongoDB のクラスターを構成するため、9台の EC2 インスタンスを使用していました。
これらの作業を9台のインスタンスに対して、定期的に実施する必要があり、大きな負担がかかっていました。
特に Amazon Linux のバージョンアップ作業は非常にコストが掛かり簡単には実施できません。
現状動作しているインスタンスに対してアップデートコマンドを気軽に実行できるものではないためです。
MongoDB を構築し直してデータを移行するような作業が必要になると想定されます。

このような課題を解決するために、MongoDB v3.2 から AWS DocumentDB への移行を決断しました。

移行先の選定

システムが抱える課題を解決するために、以下の要件を満たすフルマネージドサービスの選定をしました。

  • MongoDB v3.2 より新しいバージョンのサポート
  • 様々なモニタリング項目の提供
  • ストレージの自動スケーリング
  • 手動による OS やセキュリティアップデート作業からの解放

候補としては次のものが挙がりましたが最終的に DocumentDB のインスタンスベースを採用することにしました。

  • 1.MongoDB Atlas
  • 2.DocumentDB
    • 2.1.Elastic クラスター
    • 2.2.インスタンスベースのクラスター

以下に各サービスの特徴と採用した/採用しなかった理由について記載します。

1. MongoDB Atlas

MongoDB Atlas は、MongoDB をクラウドでホストするためのフルマネージドサービスです。
開発とサポート元の MongoDB Inc. より提供されています。

個人的に魅力に感じた点は以下の2点です。 - 公式が提供しているため、公式サポートを受けることができる - MongoDB の最新機能をいち早く試してみることができる

これまで以上に MongoDB の活用が想定される場合は MongDB Atlas を選択するのが望ましいと思います。 特にその予定がなく、DocumentDB のメリットの方が上回っていると感じたため採用を見送りました。

2. DocumentDB

DocumentDB (MongoDB 互換) は高速で信頼性が高く、完全マネージド型のデータベースサービスです。
AWS 上にシステムを構築しているため、AWS 環境内で一元管理することで運用負担を削減できることが魅力でした。
DocumentDB は、インスタンスベースのクラスターとエラスティッククラスターの 2 種類のクラスターをサポートしています。

2.1. Elastic クラスター

Elastic クラスターは、インスタンスベースのクラスターよりも高速で大容量のワークロードをサポートします。
毎秒数百万件の読み取り/書き込みとペタバイトのストレージ容量を持つことが可能です。

今回の要件ではここまでの性能は不要であり、インスタンスベースで要件を満たせると考えたため採用を見送りました。
また選定時において、MongoDB v5.0 のみのサポートであったため、(インスタンスベースは v4.0 まで選択可能だった)
バージョンアップのハードルを高く感じたことも理由の一つになります。

2.2 インスタンスベースのクラスター

RDSのように、プライマリとレプリカインスタンスを作成できるため、高可用性と読み取りスケーリングを実現できます。
また、MongoDBにおけるシャーディングを意識する必要がなく、RDSの運用感覚で簡単に管理できる点が大きなメリットです。
さらに、バージョンアップやメンテナンス時の作業も容易に行えるため、非常に魅力的です。

まとめると、以下の理由から DocumentDB を選択しました。

  • 当システムは AWS 上に構築されているため、AWS 環境内での一元管理が可能な DocumentDB に魅力を感じた
  • MongoDB の READ/WRITE 数、ストレージ使用量についてはある程度決まっているので DocumentDB Elastic クラスターほどの性能は不要
  • 慣れ親しんだ RDS 感覚で運用、メンテナンスが可能

移行までに実施したこと

DocumentDB は MongoDB v4.0 互換であったため、
現バージョンの v3.2 から v4.0 へのアップデート時に問題がないか調査とテストを実施しました。
具体的には以下になります。

1. 現在発行しているクエリの洗い出し

アップデートにより互換性が失われないか調べるため、現状使用されているクエリの洗い出しを行いました。

2. v3.2 から v4.0 へアップデート時の互換性の確認

MongoDB が提供している互換性の変更ページを中心に各バージョンごとに互換性が失われるものがないか確認しました。

3. 既存コードにおいて、テストが存在しない MongoDB 利用箇所にテスト追加

使用箇所すべてにテストコードを追加することで、以降のバージョンアップ作業において
互換性の検証がしやすくなることを期待しています。

4. 開発環境下での MongoDB v4.0 へのバージョンアップ及びテスト検証

docker image の mongo のバージョンを 3.2 から 4 へ上げ、テストコードの実行により動作検証しました。

以上の1〜4の検証を行いバージョンアップによる互換性の問題がないことが確認できました。

移行手順

移行作業としては、運用システムのダウンタイム無しで行える方法で移行することにしました。
また、問題があった場合に切り戻しがスムーズにできるよう以下の手順で実施しました。

1. 現環境(MongoDB)と並行して DocumentDB への書き込み処理を追加し、負荷の確認

現環境への書き込み処理を停止してしまうと問題が起こった際に切り戻しに時間を要してしまうため、このような構成を取ることとしました。

デメリットとして、移行期間作業中は現環境とプラスして DocumentDB の稼働コストがかかるため、
期間を決めてそこで集中して実施することが重要だと思います。
このときは負荷状況に問題がないか CPU、メモリ使用率を中心に確認を行いました。

2. 過去データを DocumentDB へ移行

全データではなく過去3年間に限定しての移行を実施しました。
3年とはいえ、データ量が多いため、一度に全データを移行してしまうと、完了までかなり時間を要することが想定されました。
長時間のデータ移行により MongoDB の負荷が上がってしまうことは避けたかったため、 1 コレクションずつ対象を限定し負荷分散させて移行することとしました。 この移行については自作スクリプトを書いて実施しました。

3. 参照箇所の切り替え

現環境(MongoDB)の参照箇所を DocumentDB へ切り替えます。
切替後はサービスに影響が出ていないか、CPU、メモリ使用率に問題がないかの確認を行いました。

4. MongoDB への書き込み処理の削除

参照箇所の切り替えをした状態で1週間ほど様子を見、問題がないことが確認できた後 MongoDB への書き込み処理を削除しました。

移行前後でのコスト比較

MongoDB on EC2 コスト

下記 EC2 のインスタンスタイプ9台でクラスターを組んでいました。

  • t2.small 3台
  • r3.xlarge 6台

コストとしては、約月額 $2,100 になります。 以下が内訳です。

  • EC2 インスタンス(オンデマンド)
    • $1,500
  • EBS
    • $600

DocumentDB コスト

DocumentDB では、db.r5.2xlarge のインスタンスクラスを使用し、プライマリ、セカンダリ構成で組みました。

コストとしては、約月額 $2,340 なります。以下が内訳です。

  • プライマリ、セカンダリインスタンス
    • $1,600
  • ストレージ
    • $20
  • I/O requests
    • $700

コストとしては移行後の方が月額 $240 高くなっています。

ストレージ料金については、不要な過去データは移行していないことと、
DocumentDB は利用しているデータ量に対しての課金であり、
EC2 のように使用分以上にプロビジョニングしておく必要がないため安くなっています。

しかし、I/O requests については想定以上にコストがかかっていました。
DocumentDB では 100 万の I/O リクエストごとに $0.20 コストが発生します。
当システムでは、月に約35億回の I/O が発生していました。

I/O は、クラスターのストレージボリュームに対して読み取りと書き込みを実行するときに Amazon DocumentDB エンジンによって実行される入出力操作です。 I/O は、100 万の I/O リクエストごとに請求されます。 検索、挿入、更新、削除などの API コール、ストリーミングや TTL インデックスの変更などの機能、mongodump や mongorestore などの ツールはすべて、ストレージボリュームからの読み取りや書き込みによって I/O を利用します。

引用: https://aws.amazon.com/jp/documentdb/pricing/

移行してみて

移行が完了してから既に2ヶ月が経過しましたが、幸いなことに、現在は問題なく稼働しています。
前に述べた4つの課題も移行後に解決でき、それにより運用コストを削減することができました。
また、移行後に改めてモニタリング項目を確認した際に、予想以上にI/O が発生していることに気づくことができました。 これに対しては、迅速な調査と解決に取り組むことができています。

特筆すべき点として、 DocumentDB のバージョンを MongoDB v4.0 互換に上げたことで、 これまで利用できなかったトランザクションを使用することができるようになりました。 これにより、今後は必要に応じて既存のコードの修正に取り組んでいく予定です。

今後の展望

1. DocumentDB のアップデート

現在は v5.0 が提供されているため、移行時には利用できなかったこの新しいバージョンにすることを考えています。 アップデートにより、より最新の機能や改善点を活用できることで、システムの性能やセキュリティ面での向上が期待できます。

2. コスト削減

先程も述べたように、現状では I/O リクエストが予想以上に発生していることが原因でコストがかさんでいます。
既に I/O リクエストを減らす手段についての調査を行い、実施可能な方法を見つけました。
インスタンスクラスのスケールダウンに繋げてコストを軽減し、効果的なコスト管理を実現していきたいです。