CPU 使用率は、ApsaraDB for MongoDB インスタンスにとって重要な監視メトリクスです。CPU 使用率が過度に高いと、MongoDB の応答が遅くなり、サービスが利用できなくなる可能性さえあります。本トピックでは、インスタンスの CPU 使用率の確認方法、高い CPU 使用率の一般的な原因、および最適化戦略について説明します。
CPU 使用率の確認方法
監視グラフの表示: ApsaraDB for MongoDB コンソールのMonitoring Information ページで、お使いのApsaraDB for MongoDB インスタンスの CPU 使用率を表示できます。収集粒度と手順の詳細については、「基本モニタリング」をご参照ください。
ApsaraDB for MongoDB は、インスタンスアーキテクチャ向けに、さまざまなノードの組み合わせを提供します。ノードを選択して、その CPU 使用率を表示できます。
レプリカセットインスタンス:レプリカセットインスタンスは、プライマリノード、1つ以上のセカンダリノード、非表示ノード、および1つ以上のオプションの読み取り専用ノードで構成されます。
シャードクラスターアーキテクチャでは、各シャードはレプリカセットとして機能するため、その CPU 使用率の分析方法はレプリカセットインスタンスと同様です。ConfigServer は設定メタデータのみを保存し、CPU ボトルネックを引き起こすことはほとんどないため、通常は無視できます。Mongos ルーティングノードの CPU 使用率は、通常、集約結果セットと同時実行リクエスト数に依存します。
CPU 使用率はインスタンスの仕様にも依存します。たとえば、インスタンスが 8 個の CPU コアと 16 GB のメモリを搭載し、CPU 使用率が 100% の場合、8 個の CPU コアがすべて使い果たされています。この例では、CPU 使用率は 800% ではなく 100% と表示されます。
一般的な原因
過剰なドキュメントスキャン
ApsaraDB for MongoDB はマルチスレッドをサポートしています。単一のクエリが多数のドキュメントをスキャンする必要がある場合、そのクエリを実行するスレッドが CPU リソースを長時間占有します。保留中のリクエストや、多数のドキュメントをスキャンする必要があるクエリが高い同時実行性で実行されると、クエリを実行するインスタンスで高い CPU 使用率が発生します。インスタンスの CPU 使用率は、インスタンス内でスキャンされるドキュメントの総数と正の相関があります。多数のドキュメントをスキャンする必要があるクエリは、次のようなシナリオでよく見られます。
フルコレクションスキャン
スロークエリログまたは system.profile コレクションで
COLLSCANキーワードが見つかった場合、クエリがフルコレクションスキャンを実行したことを意味します。system.profile コレクションを使用するには、データベースプロファイラーを有効にする必要があります。スロークエリログの表示とデータベースプロファイラーの使用方法の詳細については、「スロークエリログ」をご参照ください。クエリ実行計画の解釈方法の詳細については、「Explainの結果」および「カーソルメソッド」をご参照ください。
不適切なインデックスの設計と使用
docsExamined(スキャンされたドキュメント数) の値が 1,000 を超える、頻繁に実行されるクエリには特に注意が必要です。フルコレクションスキャンに加えて、次のような状況でもdocsExaminedの値が高くなる可能性があります。複数のフィルター条件が使用されている場合に、複合インデックスが使用されていないか、プレフィックスマッチングの原則が満たされていません。
クエリが複雑であるか、多数の集計操作を含んでおり、その結果、無効な解析ポリシーや最適化できないインデックスが生成されることがあります。
データフィールドのデータ選択性と実行頻度の判断を誤り、最適なトレードオフが達成されていません。
過剰な同時実行性
多数のサービスリクエストが送信され、同時実行性が過度に高い場合、CPU 使用率が高くなります。クエリに問題がないことを確認した場合、この高い CPU 使用率の問題は、CPU コアを追加することで解決できます。
インスタンスは高い最大総接続数をサポートしていますが、アクティブな接続を処理する能力は CPU コアによって制限されます。アクティブな接続数が CPU コア数を超えると、CPU リソースの競合によりスレッドのキューイングやタスクのバックログが発生する可能性があります。これにより、監視レポートで全体の CPU 使用率が低く表示されている場合でも、応答が遅くなることがあります。
その他の原因
多数の短期接続が確立される。 MongoDB 3.X より後のバージョンでは、デフォルトの ID 認証メカニズムは SCRAM-SHA1 であり、ハッシュ計算などの CPU を集中的に使用する操作が必要です。高い同時実行性で短期接続が確立されると、ハッシュ計算が数倍の CPU リソースを消費し、CPU リソースを使い果たすことさえあります。この場合、操作ログには多数の saslStart エラーメッセージが含まれます。PHP の短期接続が高い同時実行性で行われるシナリオを最適化するために、ApsaraDB for MongoDB では、カーネル層で組み込みのランダム関数を書き換える最適化を行いました。これにより、インスタンスの CPU 使用率を削減できます。
TTL インデックスにより、セカンダリノードの CPU 使用率がプライマリノードよりも高くなる。 この場合、ノードの高い CPU 使用率は無視できます。
MongoDB 3.2 以降は、マルチスレッドレプリケーションをサポートしています。oplog のリプレイの同時実行性は replWriterThreadCount パラメーターによって決まります。このパラメーターのデフォルト値は 16 です。セカンダリノードはサービスの書き込みを処理しません。しかし、一部のシナリオでは、セカンダリノードの CPU 使用率がプライマリノードのそれを超えることがあります。たとえば、プライマリノードのコレクションに TTL ベースの自動削除を設定した場合、システムは時間列のインデックスに基づいて効率的にデータをバッチで削除します。システムはその操作を多数の単一 delete 操作に変換してセカンダリノードに送信します。セカンダリノードでは、oplog のリプレイ効率が低いため、マルチスレッドリプレイによってそのノードの CPU 使用率が容易に上昇する可能性があります。
TTL 削除では、1 秒あたり数千の期限切れドキュメントが削除されることがあります。その結果生じる CPU 使用率とディスク I/O の上昇は、想定内の負荷です。ワークロードがより多くの容量を必要とする場合はインスタンスをスケールアップするか、断片化データのクリーンアップが完了するのを待ってからバランサーを有効にしてデータを再分散します。
シャードクラスターの場合、孤立ドキュメントがクリーンアップされた後も CPU 使用率が減少しない、または挿入パフォーマンスが改善しない場合は、さらに調査が必要です。[CloudDBA] または監視メトリクスで、各シャードのダーティキャッシュと TTL 削除率を比較します。ダーティキャッシュが高いと、アプリケーションスレッドがダーティページのフラッシュに参加することになり、あるシャードで TTL 削除率が異常に高い場合は、削除ワークロードが不均衡であることを示しています。
トラブルシューティング方法
アクティブセッションの表示と終了
正常に稼働しているインスタンスでアクティブセッションが急増し、CPU 使用率が 100% に達した場合、その原因は通常、アプリケーション側の変更にあります。一般的な原因には、スキャンするドキュメントが多すぎる、データのソートと集計、サービストラフィックの急増などがあります。次のように問題をトラブルシューティングできます。
ApsaraDB for MongoDB コンソールで、 ページに移動して、アクティブセッションを表示します。想定よりも時間がかかっているクエリを分析し、アクティブセッションを終了するか、他の是正措置を講じます。
アクティブセッションの詳細を表示および分析するには、MongoDB が提供する db.currentOp() コマンドを実行します。必要に応じて、db.killOp() コマンドを実行して、想定される実行期間内に完了しなかったスロークエリを能動的に終了します。詳細については、「db.currentOp()」および「db.killOp()」をご参照ください。
ログの記録と表示
CPU 使用率が異常に増加した場合、スロークエリログまたは監査ログを分析して、問題のあるリクエストを特定できます。COLLSCAN や docsExamined などのキーワードを確認して、過剰な数のドキュメントがスキャンされているかどうかを確認します。
監査ログ
ApsaraDB for MongoDB コンソールで、 ページに移動して、監査ログを有効化して表示します。この機能を有効にして使用する方法の詳細については、「監査ログ機能の有効化」をご参照ください。
スロークエリログ
重要過去 7 日間のスロークエリログのみ表示できます。
2021 年 6 月 6 日以降に購入したインスタンスの場合、まず監査ログ機能を有効にし、監査対象の操作タイプを [admin] および [slow] を含むように設定する必要があります。その後、スロークエリログを表示できます。監査ログが有効になった後に発生したスロークエリのみが記録されます。
ApsaraDB for MongoDB コンソールで、 ページに移動します。ビジネスニーズに基づいて、operationProfiling.mode (スロークエリモード) と operationProfiling.slowOpThresholdMs (スロークエリのしきい値) パラメーターを設定します。
MongoDB は 3 つのプロファイリングモードを提供します。
プロファイリングは無効で、データは収集されません。
すべてのリクエストに対してプロファイリングが有効になります。すべてのリクエストの実行データは system.profile コレクションに記録されます。
スロークエリに対してプロファイリングが有効になります。指定されたしきい値よりも時間がかかったクエリは system.profile コレクションに記録されます。
プロファイリングパラメータの詳細については、「データベースプロファイラー」をご参照ください。
ページで、スロークエリログを表示します。
最適化戦略
インデックスの最適化
インデックスの最適化は、単一のクエリがスキャンする必要のあるドキュメント数を減らすための最良の解決策です。基盤となるアーキテクチャでは、ApsaraDB for MongoDB は MySQL と同様のインデックス設計を使用し、MySQL よりも豊富なカテゴリと機能を提供します。したがって、MySQL に適用されるほとんどのインデックス最適化ポリシーは、ApsaraDB for MongoDB にも適用されます。
インデックスの作成と使用方法の詳細については、「ApsaraDB for MongoDB でのインデックス作成のベストプラクティス」または以下の公式ドキュメントをご参照ください。
複合インデックスの詳細については、「複合インデックス」をご参照ください。
インデックスを使用してクエリ結果をソートする方法の詳細については、「インデックスを使用したクエリ結果のソート」をご参照ください。
ヒントの詳細については、「カーソルメソッド」および「cursor.hint()」をご参照ください。
データフィールドのデータ選択性と選択頻度のバランスをとる方法の詳細については、「選択性を確保するクエリの作成」をご参照ください。
CPU コアの追加
クエリに問題がないことを確認した場合、高い CPU 使用率はサービスリクエストの数が多く、同時実行性が高いことが原因です。CPU コアを追加することで、高い CPU 使用率の問題を解決できます。ほとんどの場合、次のいずれかの方法で CPU コアを追加できます。
単一のインスタンスをスケールアップして、より多くの読み取りおよび書き込みワークロードに対応します。
レプリカセットレベルで読み書き分離を設定するか、レプリカセットに読み取り専用インスタンスを追加します。
問題のあるインスタンスをシャードクラスターインスタンスにアップグレードして、リニアなスケールアウトを実現します。
Mongos ルーティングノードの CPU が枯渇した場合は、Mongos ノードを追加して負荷分散を設定してください。 Mongos ノードの負荷分散の詳細については、「負荷分散」をご参照ください。
ApsaraDB for MongoDB インスタンスの設定を変更する方法の詳細については、「スタンドアロンインスタンスの設定を変更する」、「レプリカセットインスタンスの設定を変更する」、および「シャーディングクラスターインスタンスの設定を変更する」をご参照ください。
コレクション数と実行頻度の制御
フルコレクションスキャンを最適化するために、まずインデックスを追加することを推奨します。この方法で改善が見られなくなった場合は、アプリケーション側でコレクションのデータ量と実行頻度を制御します。
頻繁な短期接続の回避
可能な限り永続的な接続を使用することを推奨します。
よくある質問
MongoDB のバージョンアップグレード後に CPU 使用率が増加するのはなぜですか?
バージョンアップグレードによってデフォルトのパラメーターやクエリプランが変更されると、CPU 使用率が増加することがあります。以下の手順で、影響を受ける操作を特定し、最適化してください。
mongoshでdb.currentOp()を実行して、実行時間の長いリクエストや異常なリクエストを特定します。異常なopidが返された場合は、db.killOp(opid)を実行してその操作を終了します。ApsaraDB for MongoDB コンソールで、CloudDBA > インスタンスセッション ページに移動してアクティブセッションを分析し、予期しない実行時間のリクエストを見つけます。
ログの管理 > スローログ ページに移動して、コレクションスキャンやインデックスを使用しないクエリを特定します。スロークエリログの結果に基づいてインデックスを最適化します。