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 使用率はレプリカセットと同様です。config サーバーは設定メタデータのみを保存し、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 Results」および「Cursor Methods」をご参照ください。
-
不適切なインデックス設計と使用
docsExamined値 (スキャンされたドキュメント数) が 1,000 を超える、頻繁に実行されるクエリには特に注意してください。フルコレクションスキャンに加えて、次の状況でもdocsExamined値が高くなることがあります:複数のフィルター条件を使用しているにもかかわらず、複合インデックスが使用されていない、またはプレフィックス一致の原則が満たされていない場合。
クエリが複雑である、または多数の集計操作を含むため、解析ポリシーが無効になったり、インデックスを最適化できなかったりする場合。
データフィールドの選択性と実行頻度の見積もりを誤り、最適なトレードオフに到達できていない場合。
同時実行数の過多
大量のサービスリクエストが送信され、同時実行数が過度に高い場合、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 使用率が容易に上昇します。
トラブルシューティング方法
アクティブなセッションの確認と終了
通常稼働しているインスタンスの 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 コレクションに記録されます。
プロファイリングパラメーターの詳細については、「Database Profiler」をご参照ください。
-
ページで、スロークエリログを確認します。
最適化戦略
インデックスの最適化
インデックスの最適化は、単一クエリでスキャンする必要があるドキュメント数を削減する最適な方法です。基盤アーキテクチャでは、ApsaraDB for MongoDB は MySQL と類似したインデックス設計を採用しており、MySQL よりも豊富なカテゴリと機能を提供します。そのため、MySQL に適用できるインデックス最適化ポリシーの多くは、ApsaraDB for MongoDB にも適用できます。
インデックスの作成と使用方法の詳細については、「ApsaraDB for MongoDB におけるインデックス作成のベストプラクティス」または次の公式ドキュメントをご参照ください:
複合インデックスの詳細については、「Compound Indexes」をご参照ください。
インデックスを使用してクエリ結果をソートする方法の詳細については、「Use Indexes to Sort Query Results」をご参照ください。
ヒントの詳細については、「Cursor Methods」および「cursor.hint()」をご参照ください。
データフィールドの選択性と選択頻度のバランスの取り方の詳細については、「Create Queries that Ensure Selectivity」をご参照ください。
CPU コアの追加
クエリの問題がないことを確認した場合、高い CPU 使用率は、サービスリクエスト数と同時実行数が多いことが原因です。CPU コアを追加して、この高い CPU 使用率の問題を解決できます。多くの場合、次のいずれかの方法で CPU コアを追加できます:
単一インスタンスをスケールアップし、対応可能な読み取りと書き込みのワークロードを増やします。
レプリカセットレベルで読み書き分離を設定するか、レプリカセットに読み取り専用インスタンスを追加します。
問題が発生しているインスタンスをシャードクラスターインスタンスにアップグレードし、線形にスケールアウトします。
mongos ルーティングノードの CPU が使い切られている場合は、mongos ノードを追加し、それらに対してロードバランシングを設定します。mongos ノードのロードバランシングの詳細については、「Load balancing」をご参照ください。
ApsaraDB for MongoDB インスタンスの構成変更方法の詳細については、「スタンドアロンインスタンスの構成変更」、「レプリカセットインスタンスの構成変更」、および「シャードクラスターインスタンスの構成変更」をご参照ください。
コレクション数と実行頻度の制御
まず、インデックスを追加してフルコレクションスキャンを最適化することを推奨します。この方法で改善しなくなった場合は、アプリケーション側でコレクションのデータ量と実行頻度を制御してください。
短時間の接続の頻発を回避
可能な限り、永続的な接続を使用することを推奨します。