MongoDB がオペレーティング システムの mmap 機能を使用するのには理由があります。これは、少なくとも Linux システムでは、mongodb のメモリ処理が、メモリ マップ ファイルと呼ばれるオペレーティング システムの機能に基づいていることを意味します。Linux システムのメモリは、いくつかのレベルでアドレス指定されます。基本的に、どのプログラムも、32 ビット システムでは全体で 2GB、64 ビット システムでは 128TB のアドレス空間を認識します。これは仮想アドレス空間であり、32/64 ビットでは、4kb のメモリ ページ (ページはメモリの個別に処理される部分) でアドレス指定できるメモリ量を意味します。そのため、32 ビット システムで mongoDB を起動すると、そのようなシステムのデータベースは 2GB のデータしか処理できないという警告が表示されます。明らかに、この仮想アドレス空間は物理メモリの量よりも大きいため、これらの仮想アドレスと物理アドレスの間にマッピングがあります。一部の仮想アドレスは実際の物理メモリに存在するため、実際のメモリにありますが、これを保証するアルゴリズムはカーネル側にあります。Linux システムで実行されているプログラムは、仮想アドレスのみを処理できます。物理メモリにない仮想メモリ アドレスにアクセスしようとすると、ページフォールトが発生します (これは、serverStatus コマンドの追加情報フィールドで追跡できます)。(これについての簡単な説明を見つけることができます 物理メモリにない仮想メモリ アドレスにアクセスしようとすると、ページフォールトが発生します (これは、serverStatus コマンドの追加情報フィールドで追跡できます)。(これについての簡単な説明を見つけることができます 物理メモリにない仮想メモリ アドレスにアクセスしようとすると、ページフォールトが発生します (これは、serverStatus コマンドの追加情報フィールドで追跡できます)。(これについての簡単な説明を見つけることができますここで)
仮想アドレスが物理メモリに存在する場合のメモリへのアクセスは、メモリと同じくらい高速です。現在、物理メモリを持たない仮想アドレスへのアクセスは、ディスクからメモリへのページングを意味し、ディスクのランダム読み取りと同じくらい高速にメモリを読み取ります。(これにより、あなたの場合は異なります)
コレクションまたはインデックスのキャッシュを強制できるmongoDBのコマンドがあります。このコマンドはタッチ
です。最初のクエリの前にこのコマンドを使用してデータをメモリにロードすると、最初の試行で8秒で結果が得られます。残念ながら、これを常にメモリに保持するように OS に強制することはできません。そのため、メモリを使い果たしている他のものがある場合、OS はしばらくしてこのデータをページアウトします。
十分な物理メモリがある場合、mongoDB はすべてのデータとインデックスをメモリに保持します。これは必ずしも必要ではありません。大量のページフォールトを回避するためにメモリ内に存在する必要があるデータの一部があります。これはworkingsetです。db.runCommand( { serverStatus: 1, workingSet: 1 } )コマンドでワーキング セットのサイズを確認できます。
OS レベルでページングを処理することはできませんが、十分なメモリがある場合、通常、カーネルはできるだけ多くのものをキャッシュに保持することを好みます。ワーキングセットがメモリに収まる場合は、多かれ少なかれ問題ありません。一部のドキュメントがめったにアクセスされず、そこにすべてを保持するのに十分なメモリがない場合、とにかくページアウトされます。
クエリを実行すると、いくつかのことが起こります。インデックスはカバーできます。これは、クエリが何らかの概念で選択的である場合、インデックスの一部のみが操作される場合、ドキュメントがまったく操作されないことを意味します。残念ながら、メモリが十分であることを定義するのは非常に難しく、できることは監視することだけです (ワーキングセット メトリックは推定値です)。メモリ不足の症状は、このプレゼンテーションで確認できます。MMSを使用します。