翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
パフォーマンスとリソース使用率
このセクションでは、Amazon DocumentDB デプロイにおける一般的な診断の問題に関する質問と解決策を示します。提供されている例では mongo シェルを使用し、個々のインスタンスに範囲を設定しています。インスタンスエンドポイントを見つけるには、「Amazon DocumentDB エンドポイントについて」を参照してください 。
トピック
- Mongo API を使用してコレクションに対して実行された挿入、更新、削除操作の数を確認する方法
- キャッシュのパフォーマンスを分析する方法
- 長時間実行されているクエリやブロックされているクエリを見つけて終了する方法
- クエリプランを参照してクエリを最適化する方法
- Elastic クラスターのクエリプランを確認する方法
- インスタンスで実行中のすべての操作をリストする方法
- クエリの進捗状況を知る方法
- システムの実行速度が突然遅くなった理由を判断する方法
- 1 つ以上のクラスターインスタンスで CPU 使用率が高くなる原因を特定する方法
- インスタンスで開いているカーソルを確認する方法
- 現在の Amazon DocumentDB エンジンのバージョンを確認する方法
- インデックスの使用状況を分析し、未使用のインデックスを特定する方法
- 欠落しているインデックスを特定する方法
- 便利なクエリの概要
Mongo API を使用してコレクションに対して実行された挿入、更新、削除操作の数を確認する方法
特定のコレクションに対して実行された挿入、更新、削除操作の数を表示するには、そのコレクションで以下のコマンドを実行します。
db.collection.stats()
このコマンドの出力は、opCounters
フィールドの下に以下のように記述されています。
-
numDocsIns: このコレクションに挿入されたドキュメントの数。これには、
insert
およびinsertMany
コマンドを使用して挿入されたドキュメントと、アップサートによって挿入されたドキュメントが含まれます。 -
numDocsUpd: このコレクションで更新されたドキュメントの数。これには、
update
およびfindAndModify
コマンドを使用して更新されたドキュメントが含まれます。 -
NumDocsDel: このコレクションから削除されたドキュメントの数。これには
deleteOne
、deleteMany
、remove
、およびfindAndModify
コマンドを使用して削除されたドキュメントも含まれます。 -
LastReset: これらのカウンタが最後にリセットされた時刻。このコマンドによって提供される統計は、クラスターを起動/停止したり、インスタンスをスケールアップ/スケールダウンしたりするとリセットされます。
以下に示しているのは、db.collection.stats()
実行時の出力例です。
{ "ns" : "db.test", "count" : ..., "size" : ..., "avgObjSize" : ..., "storageSize" : ..., "capped" : false, "nindexes" : ..., "totalIndexSize" : ..., "indexSizes" : { "_id_" : ..., "x_1" : ... }, "collScans" : ..., "idxScans" : ..., "opCounter" : { "numDocsIns" : ..., "numDocsUpd" : ..., "numDocsDel" : ... }, "cacheStats" : { "collBlksHit" : ..., "collBlksRead" : .., "collHitRatio" : ..., "idxBlksHit" : ..., "idxBlksRead" : ..., "idxHitRatio" : ... }, "lastReset" : "2022-09-02 19:41:40.471473+00", "ok" : 1, "operationTime" : Timestamp(1662159707, 1) }
この stats コマンドは、Mongo API を使用して挿入、更新、削除操作を行うコレクション固有のカウンターを表示する場合に使用してください。コレクション固有の操作カウンターを表示するもう 1 つの方法は、DML 監査を有効にすることです。を使用した Amazon DocumentDB のモニタリング CloudWatch では、1 分間隔で発生した全コレクションの挿入、更新、削除操作の数を表示できます。
キャッシュのパフォーマンスを分析する方法
キャッシュのパフォーマンスを分析することで、データ取得の効率とシステムパフォーマンスを把握できます。分析は、キャッシュとディスクから読み取られるデータの量に基づいています。キャッシュのパフォーマンスを把握するために、キャッシュヒット (キャッシュから読み取られたデータ) とキャッシュミス (キャッシュに見つからず、ディスクから読み取られたデータ) の数に関するキャッシュ統計を提供します。特定のコレクションのキャッシュ統計は、そのコレクションで以下のコマンドを実行すると確認できます。
db.collection.stats()
このコマンドの出力の cacheStats
フィールドの値は、コレクションのキャッシュ統計と、コレクション上に作成されたインデックスの合計キャッシュ統計を提供します。これらの統計を以下に示します。
-
collBlksHit
: このコレクションの操作中にキャッシュから読み取られたブロック数。 -
collBlksRead
: このコレクションの操作中にディスクから読み込まれた (キャッシュミス) ブロック数。 -
collHitRatio
: このコレクションのキャッシュヒット率 (100 * [collBlksHit / (collBlksHit + collBlksRead)]
)。 -
idxBlksHit
: このコレクションで作成されたインデックスのキャッシュから読み取られたブロック数。 -
idxBlksRead
: このコレクションで作成されたインデックスのディスクから読み込まれた (キャッシュミス) ブロック数。 -
idxHitRatio
: このコレクションで作成されたインデックスのキャッシュヒット率 (100 * [idxBlksHit / (idxBlksHit + idxBlksRead)]
)。 -
lastReset
: これらの統計が最後にリセットされた時刻。db.collection.stats()
によって提供される統計は、クラスターを起動/停止したり、インスタンスをスケールアップ/スケールダウンしたりするとリセットされます。
各インデックスの idxBlksHit
および idxBlksRead
フィールドの内訳は、indexStats
コマンドを使用して確認することもできます。インデックス固有のキャッシュ統計は、以下のコマンドを実行して参照できます。
db.collection.aggregate([{$indexStats:{}}]).pretty()
各インデックスについて、以下のキャッシュ統計が cacheStats
フィールドの下に表示されます。
-
blksHit
: このインデックスのキャッシュから読み取られるブロック数。 -
blksRead
: このインデックスのディスクから読み取られるブロック数。 -
blksHitRatio
: キャッシュヒット率は、100 * [blksHit / (blksHit + blksRead)]
で計算され、小数点以下 4 桁に四捨五入されました。
長時間実行されているクエリやブロックされているクエリを見つけて終了する方法
ユーザークエリの実行は、最適でないクエリプランのために遅くなることも、リソースの競合のためにブロックされる可能性もあります。
クエリプランが最適でないために長時間実行されているクエリ、またはリソースの競合のためにブロックされているクエリを見つけるには、currentOp
コマンドを使用します。コマンドをフィルタリングすると、終了する関連クエリのリストを絞り込むことができます。クエリを終了できるようにするには、長時間実行されているクエリに opid
を関連付ける必要があります。
次のクエリでは、currentOp
コマンドを使用して、ブロックされている、または 10 秒以上実行されているクエリをすべてリストします。
db.adminCommand({ aggregate: 1, pipeline: [ {$currentOp: {}}, {$match: {$or: [ {secs_running: {$gt: 10}}, {WaitState: {$exists: true}}]}}, {$project: {_id:0, opid: 1, secs_running: 1}}], cursor: {} });
次に、クエリを絞り込み、10 秒以上実行されているクエリの opid
を見つけて終了できます。
10 秒以上実行されているクエリを見つけ出して終了するには
クエリの
opid
を見つけます。db.adminCommand({ aggregate: 1, pipeline: [ {$currentOp: {}}, {$match: {$or: [{secs_running: {$gt: 10}}, {WaitState: {$exists: true}}]}}], cursor: {} });
このオペレーションによる出力は、次のようになります(JSON 形式)。
{ "waitedMS" : NumberLong(0), "cursor" : { "firstBatch" : [ {
"opid" : 24646
, "secs_running" : 12 } ], "id" : NumberLong(0), "ns" : "admin.$cmd" }, "ok" : 1 }killOp
オペレーションを使用してクエリを終了します。db.adminCommand({killOp: 1, op: 24646});
クエリプランを参照してクエリを最適化する方法
クエリの実行が遅い場合は、関連するドキュメントを選択するためにクエリの実行でコレクションのフルスキャンが必要である可能性があります。場合によっては、適切なインデックスの作成により、クエリの実行を高速化できます。このシナリオを検出し、インデックスを作成するフィールドを決定するには、explain
コマンドを使用します。
注記
Amazon DocumentDB は分散型で耐障害性が高く、自己復旧ストレージシステムを利用する専用データベースエンジンで MongoDB 3.6 API をエミュレートしています。その結果、Amazon DocumentDB と MongoDB では、クエリプランと explain()
の出力が異なる場合があります。クエリプランを制御する場合は、$hint
演算子を使用して優先インデックスの選択を強制できます。
次のように、explain
コマンドで改善対象のクエリを実行します。
db.runCommand({explain: {
<query document>
}})
以下に示しているのは、オペレーションの例です。
db.runCommand({explain:{ aggregate: "sample-document", pipeline: [{$match: {x: {$eq: 1}}}], cursor: {batchSize: 1}} });
このオペレーションによる出力は、次のようになります(JSON 形式)。
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "db.test",
"winningPlan" : {
"stage" : "COLLSCAN
"
}
},
"serverInfo" : {
"host" : "...",
"port" : ...,
"version" : "..."
},
"ok" : 1
}
前述の出力は、$match
ステージでコレクション全体をスキャンし、各ドキュメントのフィールド "x"
が 1 に等しいかどうか確認する必要があることを示しています。コレクションに多くのドキュメントがある場合、コレクションのスキャン(および全体的なクエリのパフォーマンス)は非常に低速になります。したがって、explain
コマンドの出力に "COLLSCAN"
が存在することは、適切なインデックスを作成することで、クエリのパフォーマンスを向上できることを示します。
この例では、クエリはすべてのドキュメントでフィールド "x"
が 1 と等しいかどうかを確認します。したがって、フィールド "x"
でインデックスを作成すると、クエリは完全なコレクションスキャンを回避し、インデックスを使用して関連ドキュメントをより早く返すことができます。
フィールド "x"
でインデックスを作成した後、explain
出力は次のようになります。
{ "queryPlanner" : { "plannerVersion" : 1, "namespace" : "db.test", "winningPlan" : { "stage" : "
IXSCAN
", "indexName" : "x_1
", "direction" : "forward
" } }, "serverInfo" : { "host" : "...", "port" : ..., "version" : "..." }, "ok" : 1 }
フィールド "x"
にインデックスを作成すると、$match
ステージはインデックススキャンを使用して、述語 "x = 1"
を評価する必要があるドキュメントの数を減らすことができます。
小規模なコレクションで、パフォーマンスの向上がごくわずかである場合、Amazon DocumentDB クエリプロセッサはインデックスを使用しないことがあります。
Elastic クラスターのクエリプランを確認する方法
Elastic クラスターのクエリプランを調べるには、explain
コマンドを使用します。以下は、シャードコレクションを対象とする検索クエリの explain
操作の例です。
db.runCommand( { explain: { find: "cities", filter: {"name": "Seoul"}} } )
注記
Amazon DocumentDB は、目的別データベースエンジンで MongoDB をエミュレートします。その結果、クエリプランと explain()
の出力は、Amazon DocumentDB と MongoDB の間で異なる場合があります。$hint
オペレーターを使ってクエリプランを制御し、優先インデックスの選択を強制することができます。
このオペレーションによる出力は、次のようになります (JSON 形式)。
{
"queryPlanner" : {
"elasticPlannerVersion" : 1,
"winningPlan" : {
"stage" : "SINGLE_SHARD",
"shards" : [
{
"plannerVersion" : 1,
"namespace" : "population.cities",
"winningPlan" : {
"stage" : "SHARD_MERGE",
"shards" : [
{
"shardName" : "f2cf5cfd-fe9c-40ca-b4e5-298ca0d11111",
"plannerVersion" : 1,
"namespace" : "population.cities",
"winningPlan" : {
"stage" : "PARTITION_MERGE",
"inputStages" : [
{
"stage" : "COLLSCAN",
"partitionCount" : 21
}
]
}
},
{
"shardName" : "8f3f80e2-f96c-446e-8e9d-aab8c7f22222",
"plannerVersion" : 1,
"namespace" : "population.cities",
"winningPlan" : {
"stage" : "PARTITION_MERGE",
"inputStages" : [
{
"stage" : "COLLSCAN",
"partitionCount" : 21
}
]
}
},
{
"shardName" : "32c5a06f-1b2b-4af1-8849-d7c4a033333",
"plannerVersion" : 1,
"namespace" : "population.cities",
"winningPlan" : {
"stage" : "PARTITION_MERGE",
"inputStages" : [
{
"stage" : "COLLSCAN",
"partitionCount" : 22
}
]
}
}
]
},
"shardName" : "32c5a06f-1b2b-4af1-8849-d7c4a0f3fb58"
}
]
}
},
"serverInfo" : {
"host" : "example-4788267630.us-east-1.docdb-elastic.amazonaws.com:27017",
"version" : "5.0.0"
},
"ok" : 1,
"operationTime" : Timestamp(1695097923, 1)
}
上記の出力は、3 つのシャードクラスターでの find
クエリのクエリプランを示しています。各シャードには複数のデータパーティションがあり、それぞれ異なる入力ステージを設定できます。この例では、各シャード内の「PARTITION_MERGE」ステージで結果がマージされる前に、すべてのパーティションで「COLLSCAN」 (コレクションスキャン) が実行されます。その後、シャード全体の結果は「SHARD_MERGE」ステージでマージされ、その後クライアントに送り返されます。
インスタンスで実行中のすべての操作をリストする方法
ユーザーまたはプライマリユーザーが、診断およびトラブルシューティングのために、インスタンスで実行されている現在のすべてのオペレーションをリストアップしたい場合があります。(ユーザーの管理の詳細については、Amazon DocumentDB ユーザーの管理 を参照してください。)
mongo
シェルで、次のクエリを使用して、Amazon DocumentDB インスタンスで実行中のすべてのオペレーションをリストできます。
db.adminCommand({currentOp: 1, $all: 1});
クエリは、インスタンス上で現在動作しているすべてのユーザークエリと内部システムタスクの完全なリストを返します。
このオペレーションによる出力は、次のようになります(JSON 形式)。
{
"inprog" : [
{
"desc" : "INTERNAL"
},
{
"desc" : "TTLMonitor",
"active" : false
},
{
"client" : ...,
"desc" : "Conn",
"active" : true,
"killPending" : false,
"opid" : 195,
"ns" : "admin.$cmd",
"command" : {
"currentOp" : 1,
"$all" : 1
},
"op" : "command",
"$db" : "admin",
"secs_running" : 0,
"microsecs_running" : NumberLong(68),
"clientMetaData" : {
"application" : {
"name" : "MongoDB Shell"
},
"driver" : {
...
},
"os" : {
...
}
}
},
{
"desc": "GARBAGE_COLLECTION",
"garbageCollection": {
"databaseName": "testdb",
"collectionName": "testCollectionA"
},
"secs_running": 3,
"microsecs_running": NumberLong(3123456)
},
{
"desc": "GARBAGE_COLLECTION",
"garbageCollection": {
"databaseName": "testdb",
"collectionName": "testCollectionB"
},
"secs_running": 4,
"microsecs_running": NumberLong(4123456)
}
],
"ok" : 1
}
次に示すのは、"desc"
フィールドの有効な値です。
-
INTERNAL
- カーソルのクリーンアップや古いユーザーのクリーンアップタスクなどの内部システムタスク。 -
TTLMonitor
- 有効期限 (TTL) モニタリングスレッド。その実行ステータスが"active"
フィールドに反映されています。 -
GARBAGE_COLLECTION
- 内部ガベージコレクタースレッド。 -
CONN
- ユーザーのクエリ。 -
CURSOR
— 操作はユーザーが「getMore」コマンドを呼び出して次の結果のバッチを取得するのを待っているアイドルカーソルです。この状態では、カーソルはメモリを消費していますが、計算は消費されません。
前の出力では、システムで実行されているすべてのユーザークエリもリストされます。各ユーザークエリはデータベースとコレクションのコンテキストで実行され、これらの 2 つを統合したものが、名前空間と呼ばれます。各ユーザークエリの名前空間は、"ns"
フィールドで利用できます。
特定の名前空間で実行されているすべてのユーザークエリをリストする必要がある場合があります。したがって、前の出力は "ns"
フィールドでフィルタリングする必要があります。次にフィルター処理の出力を達成するためのクエリの例を示します。クエリは、データベース "db"
とコレクション "test"
(つまり、"db.test"
名前空間)で現在実行されているすべてのユーザークエリをリストします。
db.adminCommand({aggregate: 1, pipeline: [{$currentOp: {allUsers: true, idleConnections: true}}, {$match: {ns: {$eq: "db.test"}}}], cursor: {} });
システムのプライマリユーザーは、すべてのユーザーのクエリと、すべての内部システムタスクを確認できます。他のすべてのユーザーは、各自のクエリのみを表示できます。
クエリと内部システムタスクの合計数が、デフォルトのバッチカーソルサイズを超えている場合、mongo
シェルは残りの結果を表示するイテレーターオブジェクト 'it'
を自動的に生成します。すべての結果がなくなるまで、コマンド 'it'
の実行を継続します。
クエリの進捗状況を知る方法
ユーザーのクエリは、最適とはいえないクエリプランが原因で実行速度が遅くなったり、リソースの競合が原因でブロックされたりすることがあります。このようなクエリのデバッグは複数ステップのプロセスであり、同じステップを複数回実行することが必要になる場合があります。
デバッグの最初のステップでは、長時間実行されているか、ブロックされているすべてのクエリをリストします。次のクエリは、10 秒以上実行されているか、リソースを待機しているすべてのユーザークエリをリストします。
db.adminCommand({aggregate: 1, pipeline: [{$currentOp: {}}, {$match: {$or: [{secs_running: {$gt: 10}}, {WaitState: {$exists: true}}]}}, {$project: {_id:0, opid: 1, secs_running: 1, WaitState: 1, blockedOn: 1, command: 1}}], cursor: {} });
前述のクエリを定期的に繰り返して、クエリのリストが変更されているかどうかを確認し、実行時間が長いクエリまたはブロックされているクエリを識別します。
対象のクエリの出力ドキュメントに WaitState
フィールドがある場合、クエリの実行が低速であるかブロックされている理由は、リソースの競合であることを示しています。リソースの競合は、I/O、内部システムタスク、またはその他のユーザークエリが原因である可能性があります。
このオペレーションによる出力は、次のようになります(JSON 形式)。
{
"waitedMS" : NumberLong(0),
"cursor" : {
"firstBatch" : [
{
"opid" : 201,
"command" : {
"aggregate" : ...
},
"secs_running" : 208,
"WaitState" : "IO"
}
],
"id" : NumberLong(0),
"ns" : "admin.$cmd"
},
"ok" : 1
}
同じインスタンスで同時に実行されているさまざまなコレクションで多くのクエリが実行されているか、クエリを実行中のデータセットのインスタンスサイズが小さすぎると、I/O がボトルネックとなる場合があります。クエリが読み取り専用クエリである場合、各コレクションのクエリを別々のレプリカに分離することで、以前の状況を軽減できます。さまざまなコレクション間で同時更新を行う場合、またはデータセットに対するインスタンスサイズが小さすぎる場合の軽減策は、インスタンスをスケールアップすることです。
リソースの競合の原因が他のユーザークエリである場合、出力ドキュメントの "blockedOn"
フィールドに、このクエリに影響しているクエリの "opid"
が含まれます。"opid"
を使用して、すべてのクエリの "WaitState"
および "blockedOn"
フィールドのチェーンに従って、チェーンの先頭にあるクエリを調べます。
チェーンの先頭にあるタスクが内部タスクである場合の唯一の緩和策は、クエリを終了し、後で再実行することです。
以下は、検索クエリが別のタスクによって所有されているコレクションロックでブロックされるサンプル出力です。
{
"inprog" : [
{
"client" : "...",
"desc" : "Conn",
"active" : true,
"killPending" : false,
"opid" : 75,
"ns" : "...",
"command" : {
"find" : "...",
"filter" : {
}
},
"op" : "query",
"$db" : "test",
"secs_running" : 9,
"microsecs_running" : NumberLong(9449440),
"threadId" : 24773,
"clientMetaData" : {
"application" : {
"name" : "MongoDB Shell"
},
"driver" : {
...
},
"os" : {
...
}
},
"WaitState" : "CollectionLock",
"blockedOn" : "INTERNAL"
},
{
"desc" : "INTERNAL"
},
{
"client" : "...",
...
"command" : {
"currentOp" : 1
},
...
}
],
"ok" : 1
}
"WaitState"
の値が "Latch"
、"SystemLock"
、"BufferLock"
、"BackgroundActivity"
、または "Other"
の場合、リソース競合の原因は内部システムタスクにあります。この状態が長時間続く場合、唯一の緩和策は、クエリを終了し、後で再実行することです。
システムの実行速度が突然遅くなった理由を判断する方法
以下にシステムの速度が低下する一般的な理由を示します。
-
同時クエリ間の過剰なリソースの競合
-
時間の経過とともに増加するアクティブな同時クエリの数
-
"GARBAGE_COLLECTION"
などの内部システムタスク
時間の経過とともにシステムの使用状況をモニタリングするには、以下の "currentOp"
クエリを定期的に実行し、外部ストアに結果を出力します。クエリは、システムの各名前空間内のクエリとオペレーションの数をカウントします。次に、システムの使用状況の結果を分析し、システムへの負荷を把握して適切なアクションを行うことができます。
db.adminCommand({aggregate: 1, pipeline: [{$currentOp: {allUsers: true, idleConnections: true}}, {$group: {_id: {desc: "$desc", ns: "$ns", WaitState: "$WaitState"}, count: {$sum: 1}}}], cursor: {} });
このクエリは、各名前空間で実行されているすべてのクエリとすべての内部システムタスクの合計を返します。また、名前空間ごとに存在する場合は、待機状態の一意の数を返します。
このオペレーションによる出力は、次のようになります(JSON 形式)。
{
"waitedMS" : NumberLong(0),
"cursor" : {
"firstBatch" : [
{
"_id" : {
"desc" : "Conn",
"ns" : "db.test",
"WaitState" : "CollectionLock"
},
"count" : 2
},
{
"_id" : {
"desc" : "Conn",
"ns" : "admin.$cmd"
},
"count" : 1
},
{
"_id" : {
"desc" : "TTLMonitor"
},
"count" : 1
}
],
"id" : NumberLong(0),
"ns" : "admin.$cmd"
},
"ok" : 1
}
上記の出力では、コレクションロックでブロックされている名前空間 "db.test"
に 2 つのユーザークエリ、名前空間 "admin.$cmd"
に 1 つのクエリ、および 1 つの内部 "TTLMonitor"
タスクがあります。
出力が、ブロック待機状態の多くのクエリを示す場合は、「長時間実行されているクエリやブロックされているクエリを見つけて終了する方法」を参照してください。
1 つ以上のクラスターインスタンスで CPU 使用率が高くなる原因を特定する方法
以下のセクションは、インスタンスの CPU 使用率が高い原因を特定するのに役立ちます。結果は、ワークロードによって異なります。
-
インスタンスが突然遅くなる原因を特定するには、「システムの実行速度が突然遅くなった理由を判断する方法」を参照してください。
-
特定のインスタンスで長時間実行されるクエリを特定して終了するには、「長時間実行されているクエリやブロックされているクエリを見つけて終了する方法」を参照してください。
-
クエリが進行中かどうかを理解するには、「クエリの進捗状況を知る方法」を参照してください。
-
クエリの実行に時間がかかる理由を確認するには、「クエリプランを参照してクエリを最適化する方法」を参照してください。
-
実行時間が長いクエリを長期間にわたって追跡するには、「Amazon DocumentDB オペレーションのプロファイリング」を参照してください 。
インスタンスの CPU 使用率が高い理由に応じて、以下の 1 つ以上の操作を行うと役立ちます。
-
プライマリインスタンスで高い CPU 使用率が示され、レプリカインスタンスではそうではない場合、クライアントの読み込み優先設定(
secondaryPreferred
など)を使用してレプリカ間で読み込みトラフィックを分散することを検討してください。詳細については、「レプリカセットとしての Amazon DocumentDB に接続する」を参照してください。レプリカを読み込みに使用すると、プライマリインスタンスでより多くの書き込みトラフィックを処理できるようになり、クラスターのリソースをより有効に活用できます。レプリカからの読み込みには結果整合性があります。
-
CPU 使用率が高いことが書き込みワークロードの結果である場合、クラスターのインスタンスのサイズをより大きいインスタンスタイプに変更すると、ワークロードに対応する CPU コアの数が増えます。詳細については、インスタンスおよびインスタンスクラスの仕様を参照してください。
-
すべてのクラスターインスタンスで高い CPU 使用率が示され、ワークロードでレプリカが読み取りに使用されている場合、クラスターにレプリカを追加すると、読み取りトラフィックに使用できるリソースが増えます。詳細については、「クラスターへの Amazon DocumentDB インスタンスの追加」を参照してください。
インスタンスで開いているカーソルを確認する方法
Amazon DocumentDB インスタンスに接続している場合、コマンド db.runCommand("listCursors")
を使用して、そのインスタンスで開いているカーソルを一覧表示できます。特定の Amazon DocumentDB インスタンスで特定の時間に開くことができる 4,560 個までのアクティブカーソルの数は 4,560 個に制限されています。インスタンスタイプによって異なります。通常、カーソルはインスタンスのリソースを消費し、開いている数に上限があるため、不要になったカーソルは閉じることをお勧めします。特定の制限については「Amazon DocumentDB のクォータと制限事項」を参照してください。
db.runCommand("listCursors")
現在の Amazon DocumentDB エンジンのバージョンを確認する方法
現在の Amazon DocumentDB エンジンのバージョンを確認するには、次のコマンドを実行します。
db.runCommand({getEngineVersion: 1})
このオペレーションによる出力は、次のようになります(JSON 形式)。
{ "engineVersion" : "2.x.x", "ok" : 1 }
注記
Amazon DocumentDB 3.6 のエンジンバージョンは 1.x.x、Amazon DocumentDB 4.0 のエンジンバージョンは2.x.x です。
インデックスの使用状況を分析し、未使用のインデックスを特定する方法
特定のコレクションのインデックスを識別するには、次のコマンドを実行します。
db.collection.getIndexes()
コレクションに対して実行された操作中にどれだけのインデックスが使用されているかを分析するには、collStats
および indexStats
コマンドを使用できます。インデックスを使用して実行されたスキャン (インデックススキャン) の総数とインデックスなしで実行されたスキャンの数 (コレクションスキャン) を比較するには、次のコマンドを実行します。
db.collection.stats()
このコマンドの出力には、以下の値が含まれます。
-
idxScans
: インデックスを使用してこのコレクションに対して実行されたスキャンの数。 -
collScans
: インデックスを使用せずにこのコレクションに対して実行されたスキャンの数。これらのスキャンでは、コレクション内のドキュメントを一度に 1 つずつ調べる必要がありました。 -
lastReset
: これらのカウンタが最後にリセットされた時刻。このコマンドによって提供される統計は、クラスターを起動/停止したり、インスタンスをスケールアップ/スケールダウンしたりするとリセットされます。
各インデックスの使用量の内訳は、次のコマンドの出力で参照できます。パフォーマンスを向上させ、コストを削減するために、ベストプラクティスとして、未使用のインデックスを定期的に識別して削除することをお勧めします。インデックスを維持するために不必要なコンピューティング、ストレージ、I/O が使用されなくなるためです。
db.collection.aggregate([{$indexStats:{}}]).pretty()
このコマンドの出力では、コレクションで作成された各インデックスについて次の値が表示されます。
-
ops
- インデックスを使用したオペレーションの数。ワークロードが十分に長時間実行されており、ワークロードが安定していることがはっきりわかる場合、ops
値 0 は、インデックスがまったく使用されていないことを示しています。 -
numDocsRead
: このインデックスを使用する操作中に読み取られたドキュメントの数。 -
since
- インデックス使用状況に関する統計情報の収集が Amazon DocumentDB により開始されてからの時間。通常は、前回のデータベース再起動またはメンテナンスアクション以降の値です。 -
size
- このインデックスのサイズをバイト数で表す。
次の例は、上記のコマンドを実行したときの出力例です。
{
"name" : "_id_",
"key" : {
"_id" : 1
},
"host" : "example-host.com:12345",
"size" : NumberLong(...),
"accesses" : {
"ops" : NumberLong(...),
"docsRead" : NumberLong(...),
"since" : ISODate("...")
},
"cacheStats" : {
"blksRead" : NumberLong(...),
"blksHit" : NumberLong(...),
"hitRatio" : ...
}
}
{
"name" : "x_1",
"key" : {
"x" : 1
},
"host" : "example-host.com:12345",
"size" : NumberLong(...),
"accesses" : {
"ops" : NumberLong(...),
"docsRead" : NumberLong(...),
"since" : ISODate("...")
},
"cacheStats" : {
"blksRead" : NumberLong(...),
"blksHit" : NumberLong(...),
"hitRatio" : ...
}
}
コレクションの全体的なインデックスサイズを確認するには、次のコマンドを実行します。
db.collection.stats()
未使用のインデックスを削除するには、次のコマンドを実行します。
db.collection.dropIndex("indexName")
欠落しているインデックスを特定する方法
Amazon DocumentDB プロファイラを使用して、低速なクエリをログに記録 できます。低速なクエリのログに繰り返し現れるクエリがある場合、そのクエリのパフォーマンスを向上させるために追加のインデックスが必要であることを示している可能性があります。
少なくとも 1 つの COLLSCAN
ステージで実行される 1 つ以上のステージを持つ長時間実行クエリ (つまり、クエリのステージは、クエリへのレスポンスを生成するために、コレクション内のすべてのドキュメントを読み取る必要がある) を探すと、どのインデックスが役に立つ可能性があるかを見分けることができます。
次の例は、大規模なコレクションで実行されたタクシー乗車のコレクションに対するクエリを示しています。
db.rides.count({"fare.totalAmount":{$gt:10.0}}))
この例を実行するには、fare.totalAmount
フィールドにインデックスがないため、クエリはコレクションスキャン (つまり、コレクション内のすべてのドキュメントを読み込む) を実行する必要がありました。このクエリの Amazon DocumentDB プロファイラからの出力は、次のようになります。
{
...
"cursorExhausted": true,
"nreturned": 0,
"responseLength": 0,
"protocol": "op_query",
"millis": 300679,
"planSummary": "COLLSCAN",
"execStats": {
"stage": "COLLSCAN",
"nReturned": "0",
"executionTimeMillisEstimate": "300678.042"
},
"client": "172.31.5.63:53878",
"appName": "MongoDB Shell",
"user": "example"
}
この例のクエリを高速化するには、以下に示すように fare.totalAmount
にインデックスを作成します。
db.rides.createIndex( {"fare.totalAmount": 1}, {background: true} )
注記
フォアグラウンドで作成されたインデックス (つまり、インデックスの作成時に {background:true}
オプションが指定されなかった場合) は、排他的な書き込みロックを使用します。これにより、インデックス構築が完了するまでアプリケーションがコレクションにデータを書き込めなくなります。本番稼働クラスターでインデックスを作成する場合は、このような影響が生じる可能性がある点に注意してください。インデックスを作成するときは、{background:true}
を設定することをお勧めします。
一般に、カーディナリティが高いフィールド (たとえば、多数の一意の値) でインデックスを作成します。カーディナリティの低いフィールドにインデックスを作成すると、使用されないインデックスが大きくなることがあります。Amazon DocumentDB クエリオプティマイザは、クエリプランの作成時に、コレクション全体のサイズとインデックスの選択性を考慮します。インデックスが存在する場合でも、クエリプロセッサが COLLSCAN
を選択することがあります。これは、インデックスを利用しても、コレクション全体をスキャンした場合よりパフォーマンスが高くならないとクエリプロセッサが推定したときに発生します。特定のインデックスの利用をクエリプロセッサに強制する場合、以下に示すように、hint()
演算子を使用できます。
db.collection.find().hint("
indexName
")
便利なクエリの概要
以下のクエリは、Amazon DocumentDB のパフォーマンスとリソース使用率をモニタリングするのに役立ちます 。
-
以下のコマンドを使用して、オペレーションカウンター、キャッシュ統計、アクセス統計、サイズ統計など、特定のコレクションに関する統計を表示します。
db.collection.stats()
-
以下のコマンドを使用して、コレクション上に作成された各インデックスに関する統計情報 (インデックスのサイズ、インデックス固有のキャッシュ統計、インデックス使用統計など) を表示します。
db.collection.aggregate([{$indexStats:{}}]).pretty()
-
次のクエリを使用して、すべてのアクティビティをリストします。
db.adminCommand({currentOp: 1, $all: 1});
-
次のコードは、実行時間が長いクエリまたはブロックされたすべてのクエリをリストします。
db.adminCommand({aggregate: 1, pipeline: [{$currentOp: {}}, {$match: {$or: [{secs_running: {$gt: 10}}, {WaitState: {$exists: true}}]}}, {$project: {_id:0, opid: 1, secs_running: 1, WaitState: 1, blockedOn: 1, command: 1}}], cursor: {} });
-
次のコードは、クエリを終了します。
db.adminCommand({killOp: 1, op:
<opid of running or blocked query>
}); -
次のコードを使用して、システム状態の集約ビューを取得します。
db.adminCommand({aggregate: 1, pipeline: [{$currentOp: {allUsers: true, idleConnections: true}}, {$group: {_id: {desc: "$desc", ns: "$ns", WaitState: "$WaitState"}, count: {$sum: 1}}}], cursor: {} });