MongoDBのパフォーマンス監視:主要コマンドとメトリックの解説
効果的なデータベース管理は、堅牢な監視にかかっています。主要なNoSQLドキュメントデータベースであるMongoDBの場合、パフォーマンスメトリックを理解することは、高い可用性と応答性を維持するために不可欠です。低速なクエリ、過剰なリソース消費、または予期せぬ接続の急増は、アプリケーションのパフォーマンスに深刻な影響を与える可能性があります。
このガイドでは、パフォーマンス監視のために特別に設計された必須のMongoDBシェルコマンドを解説します。これらのコマンドを定期的に実行することで、管理者と開発者は、接続ステータス、クエリ実行時間、リソース使用率、および全体的な運用健全性に関する深い洞察を得ることができ、プロアクティブな最適化とトラブルシューティングが可能になります。
MongoDBシェル (mongosh) の必須監視コマンド
これらのコマンドを実行するための主要なインターフェースは、MongoDB Shell (mongosh) または従来の mongo シェルです。ここに示されているすべてのコマンドは、このシェル環境内で実行されます。
1. 現在の接続の理解: db.currentOp() と db.serverStatus()
アクティブな接続を監視することは、接続枯渇を防ぎ、リソースをブロックしている可能性のある長時間実行中の操作を特定するために不可欠です。
db.currentOp()
このコマンドは、現在データベースで実行されている操作に関する情報を返します。リアルタイムで低速またはブロッキングしているクエリを特定するために不可欠です。
使用例:
現在実行中のすべての操作を確認するには:
db.currentOp()
特定のしきい値よりも長く実行されている操作(例:5秒以上実行されている操作)を具体的に探すには:
db.currentOp({"secs_running": {$gt: 5}})
出力には、op、ns(ネームスペース)、query、secs_runningなどの詳細が含まれます。
db.serverStatus()
このコマンドは包括的なステータス情報を提供しますが、その connections セクションは接続プールと制限を監視するために重要です。
serverStatus 内の主要メトリック(接続セクション):
current: サーバーへのアクティブな接続の数。available: 確立可能な利用可能な接続の数(設定された最大値に基づく)。
db.serverStatus().connections
2. クエリパフォーマンスの分析: db.getProfilingStatus() と db.setProfilingLevel()
MongoDBには、データベース操作の実行詳細をログに記録する組み込みのプロファイリングツールが用意されており、リソースを大量に消費するクエリを特定できます。
プロファイリングレベル
プロファイリングレベルは、どの操作がログに記録されるかを決定します:
- 0 (オフ): 操作はプロファイルされません。
- 1 (低速操作): 設定されたしきい値 (
slowms) よりも遅い操作のみがプロファイルされます。 - 2 (すべての操作): すべての操作がプロファイルされます。これは大量の書き込み負荷を生成するため、特定のトラブルシューティングのために短期間のみ使用する必要があります。
ステータスの確認
現在のプロファイリングレベルを確認するには:
db.getProfilingStatus()
レベルの設定(例)
低速操作のみ(100ミリ秒を超える操作)に対してプロファイリングを有効にするには:
// slowms を 100 ミリ秒に設定します(通常、デフォルトは 100 です)
db.setProfilingLevel(1, { slowms: 100 })
ヒント: 過剰なロギングによるパフォーマンス低下を防ぐため、必要な情報を収集した後、必ずプロファイリングをレベル 0 に戻してください。
プロファイルされた低速クエリの表示
プロファイルされた操作は、監視対象の特定のデータベース内の system.profile コレクションに保存されます。過去1時間で最も遅い10個のクエリを表示するには:
db.system.profile.find().sort({millis: -1}).limit(10).pretty()
3. リソース使用率メトリック
MongoDBがCPU、メモリ、およびI/Oリソースをどのように利用しているかを理解することは、スケーリングの決定に不可欠です。
メモリとストレージの使用状況: db.serverStatus()
serverStatus 内の globalLock および storageEngine セクションは、リソース管理に関する深い洞察を提供します。
メモリインジケーター:
resident: プロセスが使用している物理メモリの量。virtual: プロセスによって割り当てられた仮想メモリの総量。
db.serverStatus().globalLock
ロック競合の監視
MongoDBは内部的なロックメカニズムを使用しています。ロックの取得と待機を監視することは、並行処理のボトルネックを特定するのに役立ちます。
globalLock 内の主要メトリック:
currentQueue.readers: ロックを待機しているリーダーの数。currentQueue.writers: ロックを待機しているライターの数。totalTime: すべての操作でロックを待機するために費やされた合計時間。
currentQueue の値が高い場合は、インデックスが不足しているか、書き込み操作が過度に長く、リーダー/ライターがキューに溜まっていることを示していることがよくあります。
4. インデックスの使用状況と健全性: db.collection.stats()
利用率の低いインデックスや欠落しているインデックスは、パフォーマンス低下の最も一般的な原因です。stats() コマンドは、インデックスの効率を分析するのに役立ちます。
特定のコレクション(例:users)で実行する場合:
db.users.stats()
確認すべき主要メトリック:
totalIndexSize: そのコレクションのすべてのインデックスによって消費されたディスク容量の合計。indexSizes: インデックスごとの領域使用量の内訳。- インデックスが存在しても読み取りに使用されない場合、それはオーバーヘッドであり、削除を検討すべきです。
5. ディスクI/Oとスループット: db.serverStatus()(ネットワークと操作)
ネットワークアクティビティと操作のレートを監視することで、データベースのスループットを把握できます。
**操作レート (opcounters から取得):
opcounters は、前回のサーバー再起動以降に実行された操作の総数を、タイプ別に分類して追跡します:
insert、query、update、delete、getmore、command。
これらのカウンターの時間経過による変化を追跡することで(例:2回の連続した serverStatus コールを比較)、操作スループット(1秒あたりの操作数)を計算できます。
比較例:
- 時刻 T1 で
db.serverStatus().opcountersを実行します。 - 時刻 T2 で
db.serverStatus().opcountersを実行します。 - T2 の値から T1 の値を減算し、その間隔で実行された操作の合計を取得します。
プロアクティブな監視のためのベストプラクティス
- 自動化が鍵: 手動のシェルコマンドのみに頼るのは非効率的です。MongoDB Cloud Manager/Ops Managerや、これらのエンドポイントを自動的に照会するサードパーティの監視ソリューションなどのツールを使用して監視を統合してください。
- ベースラインの確立: システムが健全なときにコマンドを実行して、パフォーマンスのベースラインを確立します。このベースラインからの逸脱があれば、直ちに調査が必要です。
- 遅延(レイテンシ)に焦点を当てる: 操作数は有用ですが、エンドユーザーエクスペリエンスの問題を診断する際には、生のスループットよりも遅延メトリック(プロファイリングログによって報告される時間など)を優先してください。
- 接続を頻繁にチェックする: トラフィックの多いアプリケーションでは、接続制限に最初に達することがよくあります。設定された最大値に対して
db.serverStatus().connections.currentを監視してください。
結論
db.currentOp()、db.serverStatus()、およびプロファイリングツールなどの主要なMongoDBシェルコマンドを習得することで、管理者はパフォーマンスのボトルネックを積極的に診断するために必要な手段を身につけることができます。接続プール、クエリ実行計画(プロファイリング経由)、およびリソース消費を定期的に検査することにより、MongoDBデプロイメントが高速で効率的かつ信頼性の高い状態を維持することが保証されます。