著者は、オープン・インターネット/フリースピーチ基金を寄付の受取先として選択しました。これは寄付のために書くプログラムの一環です。
導入
監視はデータベース管理の重要な部分であり、データベースのパフォーマンスや全体的な健康状態を把握することができます。データベースのパフォーマンスを監視することで、現在の容量をよりよく把握し、そのワークロードが時間とともにどのように変化するかを観察し、データベースが限界に近づいてきたときにデータベースを拡張するための計画を立てることができます。また、予期しないデータベースの使用量の急増など、ハードウェアの問題や異常な動作に気付くのに役立ちます。最後に、監視は、データベースを使用するアプリケーションに関する問題を診断するのに役立ちます。例えば、ボトルネックを引き起こすアプリケーションクエリなどです。
MongoDBには、データベースのパフォーマンスを観察するために使用できるさまざまなツールとユーティリティがインストールされています。このチュートリアルでは、組み込みのコマンドやツールを使用してデータベースのメトリクスをオンデマンドで監視する方法について学びます。また、MongoDBのデータベースプロファイラを使用して、最適化されていないクエリを検出する方法にも精通するようになります。
前提条件
このチュートリアルに従うには、次のものが必要です:
- A server with a regular, non-root user with
sudo
privileges and a firewall configured with UFW. This tutorial was validated using a server running Ubuntu 20.04, and you can prepare your server by following this initial server setup tutorial for Ubuntu 20.04. - サーバーにインストールされたMongoDB。これを設定するには、Ubuntu 20.04にMongoDBをインストールする方法のチュートリアルに従ってください。
- サーバーのMongoDBインスタンスを、認証を有効にして管理ユーザーを作成することでセキュリティで保護します。MongoDBをこのようにセキュアにするには、Ubuntu 20.04でMongoDBをセキュアにする方法のチュートリアルに従ってください。
- MongoDBコレクションのクエリと結果のフィルタリングに精通しています。MongoDBクエリの使用方法について学ぶには、MongoDBでクエリを作成する方法のガイドに従ってください。
注意: サーバーの構成、MongoDBのインストール、MongoDBインストールのセキュリティ設定に関するリンク先のチュートリアルは、Ubuntu 20.04を参照しています。このチュートリアルは、MongoDB自体に焦点を当てており、基礎となるオペレーティングシステムに関係ありません。認証が有効にされていれば、オペレーティングシステムに関係なく、一般的にどのMongoDBインストールでも機能します。
ステップ1 — テストデータの準備
MongoDBのパフォーマンスを監視する方法を説明するために、このステップでは、MongoDBシェルを開いてローカルにインストールされたMongoDBインスタンスに接続し、その中にサンプルコレクションを作成する手順を概説します。
このガイドで使用されているサンプルコレクションを作成するには、管理ユーザーとしてMongoDBシェルに接続します。このチュートリアルは、事前準備のMongoDBセキュリティチュートリアルの規則に従っており、この管理ユーザーの名前がAdminSammyであること、およびその認証データベースがadminであることを前提としています。これらの詳細を自分のセットアップに合わせて変更してください:
インストール中に設定したパスワードを入力してシェルにアクセスしてください。パスワードを入力した後、>
プロンプトサインが表示されます。
注意: 新しい接続では、MongoDBシェルはデフォルトでtestデータベースに接続します。このデータベースを使用してMongoDBとMongoDBシェルを試すことができます。
または、このチュートリアルで示されているすべての例のコマンドを実行するために、別のデータベースに切り替えることもできます。別のデータベースに切り替えるには、use
コマンドに続いてデータベースの名前を指定します:
小規模なデータセットで作業する場合、データベースシステムは任意のクエリに対してわずかなレコードしかスキャンする必要がないため、データベースのモニタリングはあまり実用的または有用ではありません。MongoDBのパフォーマンスモニタリング機能を説明するためには、MongoDBがクエリを実行するのにかなりの時間がかかる十分なデータを持つデータベースが必要です。
このガイド全体を通しての例は、多数のドキュメントを含むaccounts
というサンプルコレクションを参照しています。各ドキュメントはランダムに生成された口座残高を持つ個々の銀行口座を表します。コレクション内の各ドキュメントは、次のような構造を持ちます:
この例のドキュメントには、次の情報が含まれています:
number
: このフィールドは、指定された口座の口座番号を表します。このコレクションでは、各口座番号には1000-
の接頭辞が付いており、増加する数値識別子が続きます。currency
: このフィールドは、各口座の残高が格納されている通貨の種類を示します。各口座のcurrency
の値は、USD
またはEUR
のいずれかになります。balance
: これは、各銀行口座の残高を示します。このサンプルデータベースでは、各ドキュメントのbalance
フィールドにはランダムに生成された値が入ります。
大量のドキュメントを手動で挿入する代わりに、次のJavaScriptコードを実行してaccounts
というコレクションを同時に作成し、100万件のそのようなドキュメントを挿入することができます:
このコードは、連続して100万回for
ループを実行します。ループが繰り返されるたびに、insertOne()
メソッドがアカウントコレクションに新しいドキュメントを挿入します。各繰り返しでは、i
値によってそのイテレーションのためのnumber
フィールドの値が1000-
接頭辞と組み合わされます。これにより、このループが最初に繰り返されると、number
フィールドの値は1000-1
に設定されます。最後に繰り返されると、1000-1000000
に設定されます。
通貨は、500000より高い番号のアカウントでは常にUSD
として表され、それより低い番号のアカウントではEUR
として表されます。バランスフィールドは、Math.random()
関数を使用して0から1までのランダムな数値を生成し、そのランダムな数値に100000を乗算して大きな値を提供します。
注意: このループの実行には長い時間がかかる場合があります。操作が完了するまで実行を続けても安全です。
出力には成功の情報が含まれ、挿入された最後のドキュメントのObjectId
が返されます。
Output{
"acknowledged" : true,
"insertedId" : ObjectId("61a38a4beedf737ac8e54e82")
}
ドキュメントが正しく挿入されたことを確認するには、引数なしでcount()
メソッドを実行し、コレクション内のドキュメントの数を取得します。
Output1000000
このステップでは、パフォーマンスモニタリングに使用されるMongoDBのツールを説明するためにこのガイドで使用されるテストデータの例のリストが正常に作成されました。次のステップでは、基本的なサーバー使用状況統計を確認する方法について学びます。
ステップ2 — サーバー使用統計の確認
MongoDBは自動的に多くの有用なパフォーマンス統計を追跡します。これらを定期的にチェックすることは、データベースをモニタリングするための基本的な方法です。ただし、これらの統計はデータベースで何が起こっているかについてのリアルタイムな洞察を提供しませんが、データベースのパフォーマンスや即座の問題があるかどうかを判断するのに役立ちます。
警告: このガイドで説明されているMongoDBの監視コマンドは、データベースとそのパフォーマンスに関する機密情報を返します。このため、これらのコマンドの一部には高度な権限が必要です。
具体的には、このステップで説明されているserverStatus()
メソッド、および次のステップで強調されているmongostat
およびmongotop
コマンドは、これらを実行するにはclusterMonitor
ロールが付与されたユーザーが必要です。同様に、ステップ4で説明されているsetProfilingLevel()
メソッドにはdbAdmin
ロールが必要です。
前提条件のチュートリアル「Ubuntu 20.04でMongoDBをセキュリティ設定する方法」に従った場合、およびそのガイドで作成した管理ユーザーとしてMongoDBインスタンスに接続している場合、このガイドの例に従うためにこれらの追加の役割を付与する必要があります。
最初に、ユーザーの認証データベースに切り替えます。次の例では、これはadmin
ですが、異なる場合は独自のユーザーの認証データベースに接続してください:
Outputswitched to db admin
次に、grantRolesToUser()
メソッドを実行し、ユーザーにclusterMonitor
ロールとdbAdmin
ロールを、accounts
コレクションを作成したデータベースで付与します。次の例では、accounts
コレクションがtest
データベースにあると仮定しています:
一般的には、特定の目的に専用のユーザープロファイルを持つことがセキュリティ上より安全とされています。これにより、ユーザーが不必要に広範な権限を持つことはありません。本番環境で作業している場合は、データベースを監視するためだけの専用ユーザーを持つことが望ましいかもしれません。
以下の例では、MongoDBユーザーMonitorSammyを作成し、このチュートリアルの例に従って操作するために必要な役割を付与します。このユーザーには、クラスター内の任意のデータベースにデータを読み取りおよび書き込む権限であるreadWriteAnyDatabase
ロールも含まれていることに注意してください:
適切なロールをユーザーに付与した後は、accounts
コレクションが格納されているデータベースに戻ります:
Outputswitched to db test
stats()
メソッドを実行して、全体のデータベース統計を確認します:
このメソッドの引数(1024*1024
)は、スケールファクターであり、MongoDBにストレージ情報をメガバイト単位で返すよう指示します。これを省略すると、すべての値がバイト単位で表示されます。
stats()
メソッドは、現在のデータベースに関連する重要な統計情報を短く簡潔に返します。
Output{
"db" : "test",
"collections" : 3,
"views" : 0,
"objects" : 1000017,
"avgObjSize" : 80.8896048767171,
"dataSize" : 77.14365005493164,
"storageSize" : 24.109375,
"indexes" : 4,
"indexSize" : 9.9765625,
"totalSize" : 34.0859375,
"scaleFactor" : 1048576,
"fsUsedSize" : 4238.12109375,
"fsTotalSize" : 24635.703125,
"ok" : 1
}
この出力は、このMongoDBインスタンスが格納しているデータの概要を提供します。この出力で返される以下のキーは特に役立ちます。
objects
キーには、データベース内のドキュメントの総数が表示されます。これを使用してデータベースのサイズを評価し、時間の経過とともに成長を観察することができます。avgObjectSize
は、これらのドキュメントの平均サイズを示し、データベースが大きな複雑なドキュメントまたは小さなドキュメントで動作しているかどうかを示します。この値は常にバイト単位で表示されますが、スケールファクターを指定しているかどうかに関係なくです。collections
およびindexes
キーは、現在データベースで定義されているコレクションとインデックスの数を示します。totalSize
キーは、データベースがディスク上でどれだけのストレージを使用しているかを示します。
stats()
メソッドによって返されるこの情報は、現在のデータベースに格納されているデータの量を把握するのに役立ちますが、パフォーマンスや既存の問題についての洞察は提供しません。そのため、はるかに詳細なserverStatus()
メソッドが役立ちます。
このメソッドの出力は長く、サーバーの使用状況に関する多くの情報を提供します。
Output{
"host" : "ubuntu-mongo-rs",
"version" : "4.4.6",
"process" : "mongod",
"pid" : NumberLong(658997),
"uptime" : 976,
. . .
"ok" : 1
}
この情報はすべて有用である可能性がありますが、このガイドでは特に3つのセクションに焦点を当てます。まず、この出力のconnections
セクションを見つけてください。
Output . . .
"connections" : {
"current" : 4,
"available" : 51196,
"totalCreated" : 4,
"active" : 2,
"exhaustIsMaster" : 1,
"exhaustHello" : 0,
"awaitingTopologyChanges" : 1
},
. . .
各データベースサーバーは同時に接続できる数に限りがあります。current
キーは、現在データベースに接続しているクライアントの数を示し、available
はデータベースが利用可能な未使用の接続の数です。totalCreated
値は、サーバーの起動から使用された接続の数を保持しています。
ほとんどのアプリケーションは既存の接続を再利用し、頻繁に複数の接続を開かないように設計されています。したがって、予期していない高い接続数は、クライアントがサーバーにアクセスする方法の誤配置の危険な兆候となる可能性があります。
もし高い接続数が行われる作業負荷の特性によって予期されている場合は、複数のMongoDBインスタンス間でトラフィックを分散するために、シャーディングされたクラスターに1つ以上のシャードを追加することを検討するかもしれません。
次に、出力のglobalLock
セクションを見つけます。このセクションは、データベースサーバー全体のグローバルロックに関連しています。
Output . . .
"globalLock" : {
"totalTime" : NumberLong(975312000),
"currentQueue" : {
"total" : 0,
"readers" : 0,
"writers" : 0
},
"activeClients" : {
"total" : 0,
"readers" : 0,
"writers" : 0
}
},
MongoDBは、複数の操作を実行する際にデータの一貫性を確保するためにロックを使用し、2つのクエリが同時に同じデータを変更しないことを保証します。使用が激しいサーバーでは、ロックがボトルネックを引き起こす可能性があり、1つ以上のクエリがロックが解除されるのを待って実行される前に待機することがあります。
currentQueue.total
値は、クエリがロックが解除されるのを待機して実行できる数を示しています。この値が高い場合、データベースのパフォーマンスに影響があり、クエリの完了に時間がかかることを意味します。
これは、多くの長時間実行されるクエリがロックを保持しているために生じることがよくあり、インデックスの効果的な使用やクエリの設計の問題など、他の可能性を示している場合があります。
最後に、opcounters
セクションを見つけます:
Output "opcounters" : {
"insert" : NumberLong(10000007),
"query" : NumberLong(6),
"update" : NumberLong(6),
"delete" : NumberLong(0),
"getmore" : NumberLong(0),
"command" : NumberLong(1298)
},
このserverStatus()
の出力のセクションは、データベースサーバーが主に読み取りまたは書き込みに使用されているか、それともその使用がバランス良く行われているかを把握するのに役立ちます。この例では、テストドキュメントを挿入した後、insert
操作のカウンターがquery
操作よりもはるかに高いことが示されています。実生活のシナリオでは、これらの値はおそらく異なるでしょう。
書き込み重視のデータベースは、シャーディングを介して水平にスケーリングすることで利益を得ることができます。同様に、読み取り重視のMongoDBデータベースは通常、レプリケーションから利益を得るでしょう。
これらの統計は、サーバーがどのように使用されているかや、アクセス時に長いロック待ちキューなどのパフォーマンスの問題があるかどうかを全体的に把握するのに役立ちます。ただし、これらはサーバーのリアルタイムの使用状況に関する情報を提供しません。そのためには、mongostat
およびmongotop
コマンドが有用です。
ステップ3 — mongostat
と mongotop
を使用してリアルタイムのデータベース統計を取得する
使用されるコマンドで MongoDB のサーバー統計にアクセスすることは、サーバーが後でどのように使用されたかについての洞察を提供できますが、現時点でどのコレクションが最も活発に使用されているかやどのようなクエリが実行されているかのリアルタイム情報を提供することはできません。
MongoDB は、データベースの活動を分析し、提供される情報を継続的に更新するリアルタイムモニタリングに役立つ2つのシステムツールを提供しています: mongostat
と mongotop
。mongostat
は MongoDB インスタンスの現在の状態の簡単な概要を提供し、mongotop
はインスタンスが読み取りと書き込み操作に費やす時間を追跡します。これらのツールは、MongoDB シェルではなく、コマンドラインから実行されます。
mongostat
を使用するには、現在の MongoDB シェル接続を維持し、別のターミナルウィンドウを開いてサーバーシェルにアクセスします。2番目のサーバーシェルで、mongostat
コマンドを実行します:
以前に述べたように、mongostat
には高度な権限が必要です。 MongoDBインスタンスで認証を有効にし、適切な役割を持つユーザーを設定した場合、そのユーザーとして認証する必要があります。ユーザー名と認証データベース(この例に示すように)を提供し、プロンプトが表示されたらそのユーザーのパスワードを入力します。
デフォルトの構成では、mongostat
は現在実行中のクエリのカウンターを1秒ごとに出力します。
Outputinsert query update delete getmore command dirty used flushes vsize res qrw arw net_in net_out conn time
*0 *0 *0 *0 0 1|0 0.0% 38.7% 0 1.54G 210M 0|0 1|0 223b 84.4k 7 Nov 28 15:40:40.621
*0 *0 *0 *0 0 2|0 0.0% 38.7% 0 1.54G 210M 0|0 1|0 224b 84.8k 7 Nov 28 15:40:41.619
*0 *0 *0 *0 0 1|0 0.0% 38.7% 0 1.54G 210M 0|0 1|0 223b 84.5k 7 Nov 28 15:40:42.621
*0 *0 *0 *0 0 3|0 0.0% 38.7% 0 1.54G 210M 0|0 1|0 365b 85.0k 7 Nov 28 15:40:43.619
mongostat
の出力に特定のクエリタイプの値が0
と表示される場合、データベースはそのタイプの操作を実行していないことを示します。この例の出力は、各クエリタイプに0
が表示されており、現在アクティブに実行されているクエリはありません。
まだ最初のターミナルウィンドウが開いており、MongoDBシェルに接続されている必要があります。 accounts
コレクションにさらにいくつかのテストドキュメントを挿入し、mongostat
がアクティビティを検出するかどうかを確認してください。
これは、Step 1で実行したのと似たようなfor
-ループですが、今回はループがエントリーを10000個しか挿入しません。アカウント番号は2000
で始まり、通貨は常にUSDです。
新しいドキュメントが挿入されている間に、mongostat
の出力を確認してください。
Output. . .
*0 *0 *0 *0 0 1|0 0.0% 38.7% 0 1.54G 210M 0|0 1|0 112b 42.5k 4 Nov 28 15:50:33.294
*0 *0 *0 *0 0 0|0 0.0% 38.7% 0 1.54G 210M 0|0 1|0 111b 42.2k 4 Nov 28 15:50:34.295
755 *0 *0 *0 0 1|0 0.1% 38.8% 0 1.54G 210M 0|0 1|0 154k 79.4k 4 Nov 28 15:50:35.294
2853 *0 *0 *0 0 0|0 0.4% 39.1% 0 1.54G 211M 0|0 1|0 585k 182k 4 Nov 28 15:50:36.295
2791 *0 *0 *0 0 1|0 0.7% 39.4% 0 1.54G 212M 0|0 1|0 572k 179k 4 Nov 28 15:50:37.293
2849 *0 *0 *0 0 0|0 1.0% 39.7% 0 1.54G 213M 0|0 1|0 584k 182k 4 Nov 28 15:50:38.296
745 *0 *0 *0 0 2|0 1.1% 39.8% 0 1.54G 213M 0|0 1|0 153k 79.2k 4 Nov 28 15:50:39.294
*0 *0 *0 *0 0 0|0 1.1% 39.8% 0 1.54G 213M 0|0 1|0 111b 42.2k 4 Nov 28 15:50:40.295
*0 *0 *0 *0 0 2|0 1.1% 39.8% 0 1.54G 213M 0|0 1|0 167b 42.7k 4 Nov 28 15:50:41.293
. . .
クエリが実行されている間、mongostat
によって返される新しい行には、0
以外の値が表示されるようになります。データベースに新しいデータを挿入するクエリの数を示すinsert
列では、数秒間値が高くなりました。 mongostat
は1秒間隔でデータを表示するので、他の種類のデータベース操作に対する挿入の割合だけでなく、データベースが新しいデータを挿入する速度もわかります。この例では、サーバーはほぼ秒間3000件の挿入を達成しました。
mongostat
を使用して、クエリの種類ごとにデータベースサーバーの現在のワークロードを監視できます。MongoDBが提供する2番目のツールであるmongotop
は、コレクションごとにグループ化されたデータベースサーバーのアクティビティを表示します。
mongostat
を2番目のターミナルウィンドウで実行を停止するには、CTRL + C
を押します。その後、同じターミナルでmongotop
を実行します。同様に、認証が有効になっている場合は、適切な特権を持つユーザーとして認証する必要があります。
mongotop
は、データベース内のすべてのコレクションのリストと、時間ウィンドウ内の読み取り、書き込み、および合計で費やした時間を出力します。 mongostat
と同様に、出力は1秒ごとに更新されます。
Output2021-11-28T15:54:42.290+0000 connected to: mongodb://localhost/
ns total read write 2021-11-28T15:54:43Z
admin.system.roles 0ms 0ms 0ms
admin.system.version 0ms 0ms 0ms
config.system.sessions 0ms 0ms 0ms
config.transactions 0ms 0ms 0ms
local.system.replset 0ms 0ms 0ms
test.accounts 0ms 0ms 0ms
. . .
mongotop
でアクティビティが登録されるかどうかを確認するために、データベースにさらにいくつかのドキュメントを挿入してみてください。MongoDBシェルで次のfor
ループを実行した後、mongotop
が実行されているターミナルウィンドウを観察してください。
この時点では、mongotop
の統計情報にアクティビティが表示されます。
Output. . .
ns total read write 2021-11-28T15:57:27Z
test.accounts 127ms 0ms 127ms
admin.$cmd.aggregate 0ms 0ms 0ms
admin.system.roles 0ms 0ms 0ms
admin.system.version 0ms 0ms 0ms
config.system.sessions 0ms 0ms 0ms
config.transactions 0ms 0ms 0ms
local.system.replset 0ms 0ms 0ms
ns total read write 2021-11-28T15:57:28Z
test.accounts 130ms 0ms 130ms
admin.$cmd.aggregate 0ms 0ms 0ms
admin.system.roles 0ms 0ms 0ms
admin.system.version 0ms 0ms 0ms
config.system.sessions 0ms 0ms 0ms
config.transactions 0ms 0ms 0ms
local.system.replset 0ms 0ms 0ms
. . .
ここでは、mongotop
が、test
データベースの accounts
コレクションでのすべてのデータベースアクティビティが発生し、時間ウィンドウ内のすべての操作が書き込み操作であることを示しています。すべてこれは、実行した for
ループ操作と一致するはずです。
MongoDB のデータベースプロファイラを使用して遅いクエリを特定する
データベースのパフォーマンスボトルネックはさまざまな原因から発生する可能性があります。データベースのスケーリング(水平または垂直のどちらか)がパフォーマンスボトルネックの解決策であることがしばしばありますが、その原因は実際にはデータベースの制限ではなく、スキーマやクエリ設計の問題である場合もあります。
クエリが長時間実行される場合、その原因はインデックスの効率的な使用やクエリ自体のエラーかもしれません。長時間実行されるクエリは、通常、テストデータセットが小さすぎるか、条件が本番環境と異なるため、アプリケーション開発中に見逃されることがよくあります。
犯人を見つける方法の一つとして、テストクエリを手動で実行し、どのクエリが性能が低いかをチェックすることができますが、これは非常に手間がかかります。幸いなことに、MongoDBのデータベースプロファイラツールがこれを自動的に行うことができます。
MongoDBのデータベースプロファイラは、特定の条件に一致する場合にクエリとその実行に関する統計情報を記録することができます。これらの条件の中で最も重要なのは、クエリの実行時間です。クエリの実行に指定された時間よりも長くかかる場合、プロファイラはそのクエリを自動的に問題のあるものとしてフラグ付けします。プロファイラを使用すると、性能が低いクエリを特定し、その特定の問題に焦点を当てて修正することができます。
プロファイラを使用する前に、次のクエリを実行してください。このクエリは、挿入したアカウントの1つを取得しますが、最初の見た目ほど単純ではありません:
コマンドは、指定したアカウントを正確に取得します:
Output{ "_id" : ObjectId("61a38fd5eedf737ac8e54e96"), "number" : "1000-20", "currency" : "EUR", "balance" : 24101.14770458518 }
クエリがすぐに実行されなかったことに気づいたかもしれません。MongoDBがアカウントを見つけるのに数秒かかりました。実際のアプリケーションでは、性能が低いさまざまな種類のクエリがあり、実践ではその性能低下に気付かないかもしれません。
予想よりも時間がかかるクエリを特定するのを助けるようにMongoDBを設定することができます。それを行うには、まず次のコマンドを実行してプロファイラを有効にします:
setProfilingLevel()
メソッドには2つの引数があります。最初はプロファイリングレベルで、0
、1
、または2
のいずれかです:
0
はプロファイラを無効にします1
は条件を満たす遅いクエリのみにプロファイラを有効にします2
はすべてのクエリに対してプロファイラを有効にします。
この例では、プロファイラは第二引数 { slowms: 100 }
で定義されたように、100ミリ秒以上かかるクエリを解析します。
注意: プロファイラを使用するとパフォーマンスが低下します。MongoDB はクエリを実行するだけでなく、解析する必要があります。パフォーマンスのボトルネックを監視する際には慎重に使用する必要があります。
プロファイラがログに記録するクエリのサブセットをさらに細かく設定することができ、クエリの一定割合のみをプロファイリングしたり、クエリのタイプでフィルタリングしたりすることができます。プロファイラに対するより細かな制御方法について詳しくは、公式ドキュメントを参照してください。
このメソッドは成功メッセージを返します:
Output{ "was" : 0, "slowms" : 100, "sampleRate" : 1, "ok" : 1 }
これにより、データベースのプロファイリングが有効になり、MongoDB が実行するすべてのクエリをアクティブに監視し、100ミリ秒以上かかるクエリを見つけます。
いくつかの異なるクエリを実行して試してみてください。まず、accounts
コレクション内のドキュメント数を検索するために count
コマンドを使用してください。
このコマンドはコレクション内のドキュメント数を迅速に返します:
Output1020000
次に、コレクション内で最初の3つの銀行口座を検索してみてください。
再度、データベースは結果を迅速に返します:
Output{ "_id" : ObjectId("61ef40640f2ba52efc56ee17"), "number" : "1000-1", "currency" : "EUR", "balance" : 25393.132960293842 }
{ "_id" : ObjectId("61ef40640f2ba52efc56ee18"), "number" : "1000-2", "currency" : "EUR", "balance" : 63629.42056192393 }
{ "_id" : ObjectId("61ef40640f2ba52efc56ee19"), "number" : "1000-3", "currency" : "EUR", "balance" : 75602.12331602155 }
最後に、特定の銀行口座の検索クエリを再実行してください:
このクエリは結果を返しますが、以前と同様に、前の操作よりも少し時間がかかります:
Output{ "_id" : ObjectId("61a38fd5eedf737ac8e54e96"), "number" : "1000-20", "currency" : "EUR", "balance" : 24101.14770458518 }
プロファイラーは自分自身の出力を生成しませんが、クエリは目に見えるほど遅くなりました。代わりに、遅い操作に関する詳細は、データベース内の特別なコレクションに登録されます。その名前はsystem.profile
です。このコレクションは、常に1 MBを超えないようにするキャップ付きのコレクションです。つまり、常に最新の遅いクエリのリストのみを含みます。
プロファイラーによって識別されたクエリに関する情報を取得するには、次のようにsystem.profile
コレクションをクエリする必要があります:
このクエリは、通常のようにfind()
メソッドを使用しています。さらに、引数として{ "ts" : -1 }
を含むsort
句も含まれています。これにより、結果セットが最新のクエリでソートされます。最後に、最後にpretty()
メソッドが出力をより読みやすい形式で表示します。
各遅いクエリは通常のドキュメントとして表され、system.profile
は通常のコレクションと同様です。つまり、結果をフィルタリングしたり、ソートしたり、さらにクエリのリストを絞ったり分析するための集計パイプラインで使用したりすることができます。
結果は単一のドキュメントのみであることに注意してください。他の2つのクエリはプロファイラーをトリガーしないほど速く実行されました:
Output{
"op" : "query",
"ns" : "test.accounts",
"command" : {
"find" : "accounts",
"filter" : {
"number" : "1000-20"
},
. . .
},
"nreturned" : 1,
"keysExamined" : 0,
"docsExamined" : 1030000,
. . .
"millis" : 434,
"planSummary" : "COLLSCAN",
. . .
}
この出力には、遅いクエリの実行に関する多くの詳細が含まれています。
op
キーは、この情報がどのような操作を表しているかを示します。ここでは、find()
を使用してデータベースからデータを取得する操作を表しているので、query
です。ns
キーは、操作に関与したデータベースとコレクションを示します。出力からわかるように、この操作はtest
データベースのaccounts
コレクションをクエリしました。command
キーは、クエリ自体に関するさらなる情報を提供します。この場合、filter
サブキーにはフィルター文書全体が含まれています。op
およびcommand
フィールドからの情報を使用して、問題のクエリを再構築できます。millis
フィールドには、クエリの完了にかかった正確な時間が記載されています。この例では、ほぼ0.5秒です。docsExamined
フィールドには、結果セットを返すためにスキャンされたドキュメントの数が表示されます。nreturned
はクエリが返したドキュメントの数を表します。この例では、100万以上のスキャンから1つのドキュメントのみが返されました。planSummary
には、MongoDBがクエリを実行するために使用したメソッドが表示されます。COLLSCAN
は、フルコレクションスキャンに対応し、つまり一致する銀行口座を見つけるためにコレクション内のすべてのドキュメントを一つずつ参照しました。
すべての情報は、このクエリをMongoDBがより速く実行できるようにするインデックスの必要性を強調しています。データベースは、検査された文書の数と返された文書の数、および実行戦略の間の大きな違いから示されるように、単一の文書を見つけるためにコレクション全体を見る必要がありました。
この具体的な例では、number
フィールドに基づいてデータをフィルタリングするクエリをサポートするインデックスを作成することで、この種のクエリのパフォーマンスが直ちに向上します。実際のシナリオでは、遅いクエリの解決策は異なる場合があり、問題を引き起こしている正確なクエリに依存します。
プロファイリングセッションを終了するには、プロファイラを無効にしてプロファイリングレベルをゼロに設定します:
操作は確認メッセージとともに成功します:
Output{ "was" : 1, "slowms" : 100, "sampleRate" : 1, "ok" : 1 }
これで、データベースは裏でプロファイリングを行わずに通常の動作に戻ります。
遅いクエリがデータベースのパフォーマンスに悪影響を与えている可能性がある場合は、データベースプロファイラを使用してそれらを見つけ、その構造と実行方法をよりよく理解することができます。この情報を元に、それらを調整してパフォーマンスを向上させる準備ができます。
結論
このガイドに従うことで、MongoDBのサーバー統計情報を見つける方法や、mongotop
、mongostat
などの診断ツールの使用方法、さらにはMongoDBのデータベースプロファイラ機構の使用方法を学びました。これらを使用すると、データベースのワークロードをより良く把握し、どのコレクションが最もアクティブであるか、サーバーが主に書き込みまたは読み取りを行っているかを判断できます。また、MongoDBのパフォーマンスに影響を与えている遅いクエリを特定し、より効率的なものに置き換えることができます。
これらは、MongoDBインストールの健全性とパフォーマンスを監視し、それに対処するための選択されたツールと技術に過ぎません。これらのツールはそれぞれ、サーバーパフォーマンスに対するよりターゲットを絞った洞察を提供するためにさらに設定およびカスタマイズできます。MongoDBの公式ドキュメントを研究して、サーバーパフォーマンスを監視し、それに対処するために使用できる技術についてさらに学ぶことをお勧めします。
Source:
https://www.digitalocean.com/community/tutorials/how-to-monitor-mongodb-s-performance