MongoDBディスク容量使用率の管理と削減のためのベストプラクティス
MongoDBは、人気のNoSQLドキュメントデータベースであり、その柔軟性とスケーラビリティで知られています。しかし、プロアクティブな管理なしでは、ディスク容量の使用率が急速に増加し、パフォーマンスの低下、システムの停止、インフラストラクチャコストの増加につながる可能性があります。MongoDBがディスク容量をどのように消費するかを理解し、効果的な管理戦略を実装することは、健全で効率的なデータベース環境を維持するために不可欠です。
この記事では、MongoDBのディスク容量を管理および削減するための包括的な戦略を掘り下げていきます。コレクションの圧縮、大規模インデックスの最適化と管理、効率のためのストレージエンジン設定の構成、データライフサイクルポリシーの実装などの実践的なテクニックを探ります。これらのベストプラクティスに従うことで、不要なディスク容量の増加を防ぎ、安定した運用を確保し、MongoDBデプロイメントの寿命を延ばすことができます。
MongoDBのディスク容量消費の理解
MongoDBは、いくつかのコンポーネントにディスク容量を使用します。
- データファイル: コレクション内の実際のBSONドキュメントを格納します。
- インデックスファイル: 効率的なクエリ実行をサポートするために作成されたBツリーインデックスを格納します。
- ジャーナルファイル (WiredTiger): データファイルに適用される前に書き込み操作を記録し、データの永続性を保証します。これらは事前に割り当てられます。
- Oplog(オペレーショナルログ): レプリカセット内の特別なキャップコレクションで、すべての書き込み操作を記録します。レプリケーションに不可欠です。
- 診断データ: ログ、
mongodプロセスファイル、その他のシステム関連情報。
時間とともに、更新、削除、ドキュメントの成長(パディング)により、コレクションやインデックスが断片化したり、未使用の割り当て済みスペースを含んだりすることがあり、ディスク容量の非効率な使用につながります。この「ホワイトスペース」は、データベースがライブデータに必要としなくなっても、オペレーティングシステムによってすぐに回収されるわけではありません。
MongoDBディスク容量削減のための戦略
1. コレクションとインデックスの圧縮
圧縮操作は、データファイルとインデックスファイルをより効率的に書き直すことで、未使用のディスク容量を回収するのに役立ちます。これは、大幅なデータの削除や更新の後特に役立ちます。
コレクションの圧縮
WiredTigerストレージエンジン(MongoDB 3.2以降のデフォルト)では、compactは主に削除されたドキュメントから空きスペースを回収し、コレクションの断片化を解消します。MMAPv1のcompact操作のようにコレクションのデータファイルをゼロから再構築するわけではありません。
db.runCommand({ compact: "myCollection" })
compactの考慮事項:
compact操作はリソース集約型(CPU、I/O)であり、特に大規模なコレクションではかなりの時間がかかる可能性があります。メンテナンスウィンドウ中またはレプリカセットのセカンダリメンバーで実行するのが最善な場合が多いです。- データを新しい場所に書き換えてからスワップするため、圧縮対象のコレクションのサイズと同等の空きディスク容量が必要です。
- シャーディングされたクラスターでは、各シャードで個別に
compactを実行してください。
インデックスの再構築
インデックスも断片化することがあります。インデックスを再構築することで、スペースを回収し、クエリパフォーマンスを向上させる可能性があります。
db.myCollection.reIndex()
reIndex()の考慮事項:
- MongoDB 4.2以降、
reIndex()はオンライン操作です(新しいインデックスのために十分なディスク容量が必要です)。4.2より前のバージョンでは、データベース全体(コレクションだけでなく)に書き込みロックがかかり、他のすべての操作がブロックされます。セカンダリメンバーでreIndex()を実行し、その後プライマリをステップダウンして新しいプライマリで実行することをお勧めします。 compactと同様に、reIndex()は操作中に追加のディスク容量を必要とします。
repairDatabase(オフライン操作)
深刻な断片化やデータ破損の場合、repairDatabaseはすべてのデータファイルを再構築できます。これはオフライン操作であり、mongodインスタンスを停止する必要があります。
mongod --repair
警告: repairDatabaseは、慎重に扱わないと破壊的な操作となり、非常に時間がかかる可能性があるため、スペース回収の最終手段としてのみ使用してください。必ずバックアップを取得してください。
2. インデックスの最適化
インデックスはパフォーマンスに不可欠ですが、かなりのディスク容量を消費する可能性があります。未使用または冗長なインデックスは純粋なオーバーヘッドです。
不要なインデックスの特定と削除
インデックスがまだ必要かどうかを定期的に確認してください。
- コレクションのすべてのインデックスを一覧表示:
javascript db.myCollection.getIndexes() - インデックス使用率の監視: データベースプロファイリングを有効にする(
db.setProfilingLevel(1))か、db.collection.stats()を使用してインデックスの使用状況を確認します。クラウド監視ツールは、インデックス使用率に関する洞察をしばしば提供します。 - 重複または冗長なインデックスの特定: たとえば、
{ a: 1, b: 1 }のインデックスは、複合インデックスを使用できるクエリにとって{ a: 1 }のインデックスを冗長にします。{ a: 1, b: 1 }のインデックスは、aとbのみを含むクエリにとって{ a: 1, b: 1, c: 1 }のインデックスによってもカバーされます。
特定したら、未使用のインデックスを削除します。
db.myCollection.dropIndex("indexName")
ヒント: プロダクションに適用する前に、必ずステージング環境でインデックスを削除する影響をテストしてください。
部分インデックスの使用
部分インデックスは、指定されたフィルタ式を満たすコレクション内のドキュメントのみをインデックス付けします。これにより、インデックス付けされるドキュメントの数が減り、ディスク容量を節約し、書き込みパフォーマンスを向上させます。
db.orders.createIndex(
{ customerId: 1, orderDate: -1 },
{ partialFilterExpression: { status: "active" } }
)
このインデックスは status が "active" であるドキュメントのみを含み、ほとんどの注文が "active" でない場合はそのサイズを劇的に縮小します。