メモリ使用量は、ApsaraDB for MongoDBインスタンスを監視するための重要な指標です。 このトピックでは、ApsaraDB for MongoDBインスタンスのメモリ使用量の詳細を表示する方法と、インスタンスの高メモリ使用量の問題をトラブルシューティングする方法について説明します。
背景情報
ApsaraDB for MongoDBプロセスは、バイナリファイルと依存システムライブラリファイルをメモリにロードします。 ApsaraDB for MongoDBプロセスは、クライアントの接続管理、要求処理、およびストレージエンジンでメモリの割り当てと解放も行います。 デフォルトでは、ApsaraDB for MongoDBはGoogleが提供するTCMallocをメモリアロケーターとして使用します。 WiredTigerストレージエンジン、クライアント接続、および要求処理によって大量のメモリが消費されます。
アクセス方式
シャードクラスタインスタンスの場合、各シャードノードのメモリ使用量はレプリカセットインスタンスのメモリ使用量と同じです。 ConfigServerノードには、構成メタデータのみが格納されます。 mongosノードのメモリ使用量は、集計結果セット、接続数、およびメタデータのサイズの影響を受けます。
レプリカセットインスタンスの場合、次の方法を使用してメモリ使用量を表示できます。
モニタリングチャートでのメモリ使用量の表示
ApsaraDB for MongoDBレプリカセットインスタンスは、複数のノードロールで構成されています。 各ノード役割は、1つ以上の物理ノードに対応することができる。 ApsaraDB for MongoDBレプリカセットインスタンスは、読み書き操作をサポートするプライマリノード、1つ以上の高可用性セカンダリノード、隠しノード、および1つ以上のオプションの読み取り専用ノードで構成されます。
ApsaraDB for MongoDBコンソールのApsaraDB for MongoDBレプリカセットインスタンスの [モニタリングデータ] ページで、インスタンスのメモリ使用量をモニタリングチャートで表示できます。
コマンドを実行してメモリ使用量を表示する
ApsaraDB for MongoDBレプリカセットインスタンスのメモリ使用量を表示および分析するには、mongoシェルで
db.serverStatus().mem
コマンドを実行します。 サンプル結果:{ "bits" : 64, "resident" : 13116, "virtual" : 20706, "supported" : true } // resident indicates the physical memory that is consumed by mongos nodes. Unit: MB. // virtual indicates the virtual memory that is consumed by mongos nodes. Unit: MB.
説明serverStatusコマンドの詳細については、「serverStatus」をご参照ください。
一般的な原因
WiredTigerストレージエンジンの高メモリ使用率
WiredTigerストレージエンジンは、ApsaraDB for MongoDBインスタンスの最大メモリ量を消費します。 互換性とセキュリティを確保するために、ApsaraDB for MongoDBはCacheSizeパラメーターをインスタンスの実際のメモリの60% に設定します。 詳細については、「仕様」をご参照ください。
キャッシュされたデータのサイズが指定されたキャッシュサイズの95% を超えると、高いメモリ使用量が発生します。 この場合、元々ユーザー要求を処理していたスレッドは、保護目的でダーティページをも追い出します。 その結果、ユーザ要求の輻輳が発生します。 詳細については、「立ち退きパラメーター」をご参照ください。
次の方法を使用して、WiredTigerストレージエンジンのメモリ使用量を表示できます。
mongo shellで
db.serverStatus().wiredTiger.ca che
コマンドを実行します。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"), ...... }
DASコンソールのインスタンスの [ダッシュボード] ページで、WiredTigerキャッシュ内のダーティデータの割合を表示します。 詳細については、「パフォーマンスの傾向」をご参照ください。
ApsaraDB for MongoDBのmongostatツールを使用して、WiredTigerキャッシュ内のダーティデータの割合を表示します。 詳細については、「mongostat」をご参照ください。
接続とリクエストのメモリ使用率が高い
インスタンスへの多数の接続が確立されている場合、次の理由によりメモリが消費される可能性があります。
各接続には、バックグラウンドで要求を処理するスレッドがあります。 各スレッドは最大1 MBのスタックスペースを占有できます。 ほとんどの場合、数十から数百KBのスタックスペースがスレッドによって占有されます。
各TCP接続には、カーネル層に読み取りバッファと書き込みバッファがあります。 バッファサイズは、TCP_rmemやtcp_wmemなどのtcpカーネルパラメーターによって決まります。 バッファサイズを指定する必要はありません。 しかしながら、多数の同時接続は、より大量のソケットキャッシュ空間を占有し、TCPのより高いメモリ使用をもたらします。
各要求は、一意のコンテキストを有します。 複数の一時バッファを、要求パケット、応答パケット、および順序付けプロセスに割り当てることができる。 一時バッファは、各要求の終わりに徐々に解放されます。 バッファは、最初にTCMallocキャッシュに解放され、次に徐々にオペレーティングシステムに解放されます。
ほとんどの場合、TCMallocはリクエストによって消費されたメモリを迅速に解放できないため、メモリ使用率が高くなります。 要求は、メモリがオペレーティングシステムに解放される前に、最大数十GBのメモリを消費することがあります。 TCMallocがオペレーティングシステムにリリースしていないメモリのサイズを照会するには、
db.serverStatus().tcmalloc
コマンドを実行します。 TCMallocキャッシュサイズは、pageheap_free_bytesとtotal_free_bytesパラメーターの値の合計です。 サンプル出力:{ "generic":{ "current_allocated_bytes":NumberLong("9641570544"), "heap_size":NumberLong("19458379776") }, "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インスタンスのデータベース、コレクション、およびインデックスが含まれます。 インスタンス内の多数のコレクションとインデックスによって消費されるメモリに注意する必要があります。 完全な論理バックアップは、特にMongoDB 4.0より前のバージョンを実行するApsaraDB for MongoDBインスタンスで多数のファイルハンドルを開く可能性があります。 ファイルハンドルは、すぐにオペレーティングシステムに戻されず、メモリ使用量の急激な増加をもたらす可能性があります。 ApsaraDB for MongoDBインスタンスの多数のコレクションが削除され、メモリリークが発生した場合、ファイルハンドルは削除できません。
インデックス作成の高メモリ使用率
通常のデータ書き込みでは、セカンダリノードは、データ再生のためにサイズが約256 MBのバッファを維持します。 プライマリノードがインデックスを作成した後、セカンダリノードはデータ再生のためにより多くのメモリを消費する場合があります。 MongoDBインスタンスより前のバージョンを実行するApsaraDB for MongoDB 4.2では、プライマリノードのバックグラウンドでインデックスが作成されます。 インデックス作成のためのシリアルリプレイは、最大500 MBのメモリを消費する場合があります。 MongoDB 4.2以降を実行するApsaraDB for MongoDBインスタンスでは、インデックスはバックグラウンドで作成できず、セカンダリノードはインデックス作成の並列再生を実行できます。 この場合、複数のインデックスが同時に作成されるとインスタンスのメモリ不足 (OOM) エラーが発生する可能性があるため、より多くのメモリが消費されます。
詳細については、「index-build-impact-on-database-performance」および「index-build-process」をご参照ください。
PlanCacheの高メモリ使用率
リクエストに多数の実行プランがある場合、PlanCacheメソッドは大量のメモリを消費する可能性があります。 以降のバージョンを実行するApsaraDB for MongoDBインスタンスで、mgset-xxx:PRIMARY> db.serverStatus().metrics.query.planCacheTotalSizeEstimateBytes
コマンドを実行して、PlanCacheのメモリ使用量を表示します。 詳細については、「バランサーが作業を行う間にセカンダリノードメモリが発生する」をご参照ください。
解決策
メモリ最適化の目標は、メモリ使用量を最小限に抑えるのではなく、リソース消費とパフォーマンスのバランスを求めることです。 理想的には、メモリは十分で安定したままであり、システムパフォーマンスは影響を受けません。 ApsaraDB for MongoDBで指定されたCacheSizeパラメーターの値を変更することはできません。 メモリ使用量を最適化するには、次の方法を使用することを推奨します。
同時接続の数を制御します。 100の永続的な接続は、パフォーマンステストの結果に基づいてデータベースに確立できます。 デフォルトでは、MongoDBドライバーはバックエンドとの100接続プールを確立できます。 多数のクライアントが存在する場合は、各クライアントの接続プールのサイズを小さくします。 データベースに1,000個以下の永続的な接続を確立することをお勧めします。 そうしないと、メモリおよびマルチスレッドコンテキストのオーバーヘッドが増加し、要求処理の待ち時間が長くなる可能性があります。
単一のリクエストのメモリオーバーヘッドを削減します。 たとえば、インデックスを作成してコレクションスキャンの数を減らし、メモリの順序付けを実行できます。
接続数が適切であってもメモリ使用量が増え続ける場合は、メモリ設定をアップグレードすることを推奨します。 そうしないと、OOMエラーと大規模なキャッシュクリアにより、システムパフォーマンスが急激に低下する可能性があります。
TCMallocのメモリ解放を加速します。 インスタンスのメモリ使用量が80% を超える場合は、ApsaraDB for MongoDBコンソールでTCMallocパラメーターを調整してメモリ使用量を最適化できます。 tcmallocAggressiveMemoryDecommitパラメーターを優先的に有効にします。 このパラメータはリッチプラクティスによって検証されており、メモリの問題の解決に大きな影響を与えます。 パラメーターの調整後に期待される効果をアーカイブしない場合は、tcmallocReleaseRateパラメーターの値を徐々に増やしてください。 たとえば、初期パラメーター値が1の場合、値を最初に3に調整し、次に5に調整します。
重要オフピーク時には、tcmallocAggressiveMemoryDecomitおよびtcmallocReleaseRateパラメーターの値を調整することを推奨します。 調整は、パフォーマンスの低下を引き起こす可能性がある。 ビジネスが調整の影響を受ける場合は、パラメーター値をタイムリーにロールバックします。
メモリリークが発生する可能性があるシナリオでは、Alibaba Cloudテクニカルサポートにお問い合わせください。ApsaraDB for MongoDB
関連ドキュメント
立ち退きパラメータ
パラメーター | デフォルト値 | 説明 |
eviction_target | 80 | 使用するキャッシュサイズがeviction_targetパラメーターの値より大きい場合、削除スレッドはバックグラウンドでページを削除します。 |
eviction_trigger | 95 | 使用されるキャッシュサイズがeviction_triggerパラメーターの値より大きい場合、ユーザースレッドはバックグラウンドでクリーンページを追い出します。 |
eviction_dirty_target | 5 | キャッシュ内のダーティデータのサイズがeviction_dirty_targetパラメーターの値より大きい場合、削除スレッドはバックグラウンドでダーティページを削除します。 |
eviction_dirty_trigger | 20 | キャッシュ内のダーティデータのサイズがeviction_dirty_triggerパラメーターの値より大きい場合、ユーザースレッドはバックグラウンドでダーティページを追い出します。 |