メモリ使用率は、ApsaraDB for MongoDB インスタンスを監視するための重要なメトリックです。このトピックでは、ApsaraDB for MongoDB インスタンスのメモリ使用率の詳細を表示する方法と、インスタンスにおけるメモリ使用率が高い問題のトラブルシューティング方法について説明します。
背景情報
ApsaraDB for MongoDB プロセスは、バイナリファイルと依存システムライブラリファイルをメモリにロードします。 ApsaraDB for MongoDB プロセスは、クライアント接続管理、リクエスト処理、および WiredTiger ストレージエンジンでもメモリを割り当てて解放します。デフォルトでは、ApsaraDB for MongoDB は、Google が提供する TCMalloc をメモリアロケータとして使用します。大量のメモリは、WiredTiger ストレージエンジン、クライアント接続、およびリクエスト処理によって消費されます。
アクセス方法
モニタリングチャートでメモリ使用率を表示する
ApsaraDB for MongoDB コンソールの ApsaraDB for MongoDB インスタンスの [モニタリングデータ] ページで、モニタリングチャートでインスタンスのメモリ使用率を表示できます。 ApsaraDB for MongoDB は、インスタンスアーキテクチャにさまざまなノードの組み合わせを提供します。ノードを選択して、そのメモリ使用率を表示できます。
レプリカセットインスタンス レプリカセットインスタンスは、プライマリノード、1 つ以上のセカンダリノード、非表示ノード、および 1 つ以上のオプションの読み取り専用ノードで構成されます。
シャードクラスターインスタンス シャードクラスターインスタンスは、1 つ以上のシャードコンポーネント、構成メタデータを格納する ConfigServer コンポーネント、および 1 つ以上の Mongos コンポーネントで構成されます。シャードコンポーネントのメモリ消費量は、レプリカセットインスタンスのメモリ消費量と同じです。 Mongos コンポーネントのメモリ使用率は、集約結果セット、接続数、およびメタデータサイズによって異なります。
コマンドを実行してメモリ使用率を表示する
インスタンスのメモリ使用率を表示および分析するには、mongo シェルを使用して インスタンスに接続し、
db.serverStatus().mem
コマンドを実行します。出力例:
{ "bits" : 64, "resident" : 13116, "virtual" : 20706, "supported" : true }
// resident は、Mongos ノードによって消費される物理メモリを示します。単位:MB。
// virtual は、Mongos ノードによって消費される仮想メモリを示します。単位:MB。
serverStatus コマンドの詳細については、「serverStatus」をご参照ください。
一般的な原因
WiredTiger ストレージエンジンのメモリ使用率が高い
WiredTiger ストレージエンジンは、ApsaraDB for MongoDB インスタンスの最大のメモリを消費します。互換性とセキュリティを確保するために、ApsaraDB for MongoDB は、CacheSize パラメーターをインスタンスの実際のメモリの 60% に設定します。詳細については、「仕様」をご参照ください。
ストレージエンジンのキャッシュが指定した CacheSize 値の 95% に達すると、インスタンスの負荷が高くなり、ユーザーリクエストを処理するために使用されるスレッドがクリーンページをエビクトします。ストレージエンジンのキャッシュ内のダーティデータの割合が 20% を超えると、ユーザースレッドはダーティページをエビクトします。このプロセスでは、ユーザーは明らかにリクエストがブロックされているのを確認します。詳細については、「エビクションパラメーター」をご参照ください。
次の方法を使用して、WiredTiger ストレージエンジンのメモリ使用量を表示できます。
WiredTiger エンジンのメモリ使用量を表示する
mongo シェルで
db.serverStatus().wiredTiger.cache
コマンドを実行します。bytes currently in the cache
パラメーターの値はメモリサイズです。結果例:{ ...... "bytes belonging to page images in the cache":6511653424, "bytes belonging to the cache overflow table in the cache":65289, "bytes currently in the cache":8563140208, "bytes dirty in the cache cumulative":NumberLong("369249096605399"), ...... }
WiredTiger キャッシュ内のダーティデータの割合を表示する
DAS コンソールのインスタンスの リアルタイムモニタリング ページで、WiredTiger キャッシュ内のダーティデータの割合を表示します。
ApsaraDB for MongoDB の mongostat ツールを使用して、WiredTiger キャッシュ内のダーティデータの割合を表示します。詳細については、「mongostat」をご参照ください。
接続とリクエストのメモリ使用率が高い
インスタンスへの多数の接続が確立されている場合、次の理由により、メモリの一部が消費される可能性があります。
スレッドダンプのオーバーヘッド。各接続には、バックグラウンドでリクエストを処理するスレッドがあります。各スレッドは最大 1 MB のスレッドダンプ領域を占有できます。ほとんどの場合、数十から数百 KB のスレッドダンプ領域がスレッドによって占有されます。
TCP 接続バッファー。各 TCP 接続には、カーネル層に読み取り/書き込みバッファーがあります。バッファーサイズは、tcp_rmem や tcp_wmem などの TCP カーネルパラメーターによって決まります。バッファーサイズを指定する必要はありません。ただし、多数の同時接続は、より多くのソケットキャッシュ領域を占有し、TCP のメモリ使用量の増加につながります。
TCMalloc メモリ管理。各リクエストには固有のコンテキストがあります。リクエストパケット、レスポンスパケット、および順序付けプロセスに複数のテンポラリバッファーが割り当てられる場合があります。テンポラリバッファーは、各リクエストの最後に徐々に解放されます。バッファーは最初に TCMalloc キャッシュに解放され、次に徐々にオペレーティングシステムに解放されます。ほとんどの場合、TCMalloc がリクエストによって消費されたメモリを迅速に解放できないため、メモリ使用率が高くなります。リクエストは、メモリがオペレーティングシステムに解放される前に、最大数十 GB のメモリを消費する可能性があります。
接続とリクエストのメモリ使用率が高い問題のトラブルシューティングには、次のいずれかの方法を使用できます。
接続使用率を表示する
ApsaraDB for MongoDB コンソールの ApsaraDB for MongoDB インスタンスの [モニタリングデータ] ページで、モニタリングチャートでインスタンスのメモリ使用量を表示できます。
mongo シェルを使用して、インスタンスへの接続数をクエリします。
TCMalloc がオペレーティングシステムに解放していないメモリのサイズを表示する
TCMalloc がオペレーティングシステムに解放していないメモリのサイズをクエリするには、
db.serverStatus().tcmalloc
コマンドを実行します。 TCMalloc キャッシュサイズは、pageheap_free_bytes 値と total_free_byte 値の合計です。結果例:{ ...... "tcmalloc":{ "pageheap_free_bytes":NumberLong("3048677376"), "pageheap_unmapped_bytes":NumberLong("544994184"), "current_total_thread_cache_bytes":95717224, "total_free_byte":NumberLong(1318185960), ...... } }
説明TCMalloc の詳細については、「tcmalloc」をご参照ください。
メタデータのメモリ使用率が高い
データベース、コレクション、インデックスなど、ApsaraDB for MongoDB 内の大量のメタデータは、大量のメモリを消費する可能性があります。以前のバージョンを実行している ApsaraDB for MongoDB インスタンスでは、次の問題が発生する可能性があります。
MongoDB 4.0 より前のバージョンを実行しているインスタンスでは、完全論理バックアップによって多数のファイルハンドルが開かれる可能性があります。ファイルハンドルがオペレーティングシステムに迅速に返されない場合、メモリ使用量が急激に増加します。
MongoDB 4.0 以前を実行しているインスタンスで多数のコレクションが削除された後、ファイルハンドルが削除されない場合があります。これにより、メモリリークが発生します。
インデックス作成のメモリ使用率が高い
通常のデータ書き込みでは、セカンダリノードはデータリプレイ用に約 256 MB のバッファーを保持します。インデックスが作成された後、データリプレイのためにセカンダリノードによってより多くのメモリが消費される可能性があります。
インデックス作成中に、
background
オプションは MongoDB 4.2 より前のバージョンを実行しているインスタンスで使用できます。{background:true}
を構成すると、インデックスはバックグラウンドで作成されます。インデックス作成はシリアル方式でリプレイされます。これにより、最大 500 MB のメモリが消費されます。デフォルトでは、
background
オプションは MongoDB 4.2 以降を実行しているインスタンスでは非推奨です。セカンダリノードはインデックス作成を並列方式でリプレイできますが、これにより多くのメモリが消費されます。複数のインデックスが作成されると、メモリ不足エラーが発生する可能性があります。
詳細については、「index-build-impact-on-database-performance」および「index-build-process」をご参照ください。
PlanCache のメモリ使用率が高い
リクエストに多数の実行プランがある場合、PlanCache メソッドは大量のメモリを消費する可能性があります。
PlanCache のメモリ使用量を表示する:db.serverStatus().metrics.query.planCacheTotalSizeEstimateBytes
コマンドを実行して、MongoDB 4.0 以降を実行しているインスタンスの PlanCache のメモリ使用量を表示できます。
インスタンスが MongoDB 4.0 を実行しているが、前のコマンドに関連するフィールドが含まれていない場合、インスタンスのマイナーバージョンが低すぎます。 インスタンスのマイナーバージョンを更新することをお勧めします。
PlanCache のメモリ使用量の詳細は、「Secondary node memory arise while balancer doing work」をご参照ください。
最適化ポリシー
メモリ最適化の目標は、メモリ使用量を最小限に抑えるのではなく、リソース消費量とパフォーマンスのバランスをとることです。理想的には、メモリは十分で安定しており、システムパフォーマンスに影響を与えません。
ApsaraDB for MongoDB によって指定された CacheSize パラメーターの値を変更することはできません。メモリ最適化には、次のポリシーを使用できます。
同時接続数を制御します。パフォーマンステストの結果に基づいて、データベースに 100 の持続的接続を確立できます。デフォルトでは、MongoDB ドライバーはバックエンドと 100 の接続プールを確立できます。多数のクライアントが存在する場合は、各クライアントの接続プールのサイズを縮小します。データベースに 1,000 を超える持続的接続を確立しないことをお勧めします。そうしないと、メモリとマルチスレッドコンテキストのオーバーヘッドが増加し、リクエスト処理のレイテンシが高くなる可能性があります。
単一のリクエストのメモリオーバーヘッドを削減します。たとえば、クエリのパフォーマンスを最適化するには、インデックスを作成して、コレクションスキャンとメモリ内ソートの必要性を最小限に抑えることができます。
メモリ構成をスペックアップします。接続数が適切であるが、クエリのパフォーマンスを最適化した後もメモリ使用量が増え続ける場合は、メモリ構成をスペックアップすることをお勧めします。そうしないと、メモリ不足 (OOM) エラーと広範なキャッシュクリアにより、インスタンスの可用性に影響を与える可能性があります。
TCMalloc のメモリ解放を高速化します。インスタンスのメモリ使用率が 80% を超える場合は、ApsaraDB for MongoDB コンソールで TCMalloc パラメーターを調整できます。
優先的に tcmallocAggressiveMemoryDecommit パラメーターを有効にします。このパラメーターは豊富な実践によって検証されており、メモリの問題の解決に大きな効果があります。
tcmallocReleaseRate パラメーターの値を徐々に増やします。 tcmallocAggressiveMemoryDecommit パラメーターを調整した後も要件を満たさない場合は、tcmallocReleaseRate パラメーターの値を徐々に増やします。たとえば、パラメーター値を 1 から 3 に、次に 5 に増やすことができます。
重要オフピーク時に tcmallocReleaseRate パラメーターの値を調整することをお勧めします。2 つのパラメーターの調整により、パフォーマンスが低下する可能性があります。調整によってビジネスに影響が及ぶ場合は、パラメーター値をタイムリーにロールバックしてください。
データベースとコレクションの数を最適化します。インスタンスに過剰な数のデータベースとコレクションが含まれている場合は、不要なコレクションとインデックスを削除するか、複数のコレクションのデータを統合するか、インスタンスを分割するか、インスタンスデータをシャードクラスターインスタンスに移行できます。詳細については、「多数のデータベースとコレクションが原因でインスタンスがスタッター状態になった場合、または例外が発生した場合はどうすればよいですか?」をご参照ください。
ApsaraDB for MongoDB の使用でメモリリークが発生する可能性のあるシナリオでは、Alibaba Cloud テクニカルサポートにお問い合わせください。
参考資料
エビクションパラメーター
パラメーター | デフォルト値 | 説明 |
eviction_target | 80% | 使用済みキャッシュサイズが eviction_target パラメーターの値よりも大きい場合、エビクションスレッドはバックグラウンドでクリーンページをエビクトします。 |
eviction_trigger | 95% | 使用済みキャッシュサイズが eviction_trigger パラメーターの値よりも大きい場合、ユーザースレッドはバックグラウンドでクリーンページをエビクトします。 |
eviction_dirty_target | 5% | キャッシュ内のダーティデータのサイズが eviction_dirty_target パラメーターの値よりも大きい場合、エビクションスレッドはバックグラウンドでダーティページをエビクトします。 |
eviction_dirty_trigger | 20% | キャッシュ内のダーティデータのサイズが eviction_dirty_trigger パラメーターの値よりも大きい場合、ユーザースレッドはバックグラウンドでダーティページをエビクトします。 |
eviction_updates_target | 2.5% | キャッシュ更新率が eviction_updates_target パラメーターの値を超えると、バックグラウンドエビクトスレッドは小さなオブジェクトに関連するメモリ断片化スペースの削除を開始します。 |
eviction_updates_trigger | 10% | キャッシュ更新率が eviction_updates_trigger パラメーターの値を超えると、ユーザースレッドも小さなオブジェクトに関連するメモリ断片化スペースのエビクトを開始します。 |
FAQ
ApsaraDB for MongoDB の集約操作で消費されるメモリーの上限を指定するにはどうすればよいですか?
ApsaraDB for MongoDB では、集約操作で消費されるメモリーの上限を直接指定することはできません。 ApsaraDB for MongoDB の集約操作の各ステージのメモリー制限は 100 MB です。ステージがこの制限を超えると、システムはエラーを報告します。この問題を解決するには、集約ステートメントに {allowDiskUse:true}
値を指定するオプションを追加できます。詳細については、「メモリーの制限」をご参照ください。 MongoDB 6.0 以降では、グローバルデフォルトパラメーター allowDiskUseByDefault がサポートされています。集約操作で過剰なメモリが消費されると、ApsaraDB for MongoDB は一時的にディスク領域を使用して、過剰なメモリ使用を回避します。メモリ使用量を削減するためのその他のポリシーについては、「最適化ポリシー」をご参照ください。