Atlas Search インデックス パフォーマンス
項目一覧
リソース要件
インデックスのサイズと構成
重要
インデックスオブジェクトが または を超えるコレクションに対して Atlas Searchインデックスを作成する場合は、2.1 numPartitions
または を使用してクラスターをシャードする 必要があります 。インデックス パーティションは、パーティションごとに 2.1 オブジェクトに制限されています。
Atlas Search インデックスを作成すると、フィールドマッピングはデフォルトで動的になります。つまり、コレクション内の動的にインデックスを作成できるすべてのデータ型が、Atlas Search によって動的にインデックス化されます。 強調表示を有効にするなどの他のオプションも、インデックスがより多くのディスク領域を使用する可能性があります。 Atlas Search インデックスのサイズとパフォーマンス フットプリントは、次の方法で縮小できます。
注意
M0
、 M2
、およびM5
クラスター上の Atlas Search にはのみ一部の制限が適用されます。 詳細については、「 Atlas Search の無料層と共有層の制限 」を参照してください。
Considerations
一部のインデックス構成オプションは、ディスク領域の大部分を消費するインデックスにつながる可能性があります。 場合によっては、インデックスがデータのサイズの数倍になることもあります。 これは期待される動作ですが、次のインデックスを集中的に作成する機能に注意することが重要です。
オートコンプリート
Atlas Search のオートコンプリート演算子を使用して、アプリケーションに入力しながら検索するのと同様の機能を構築できます。 Atlas Search のオートコンプリートフィールド タイプは、特に次の場合に大規模なインデックスを生成する可能性があります。
nGram
トークン化を使用しています。minGrams
からmaxGrams
までの幅広い範囲を設定します。数百万のドキュメントを含むコレクションで、
1
のminGram
値を設定します。
次の操作を行うことで、 autocomplete
型インデックスで使用されるスペースを削減できます。
minGrams
とmaxGrams
の範囲を最小に縮小します。 一般的には、クエリするフィールド内の最も長い単語の文字数にmaxGrams
を設定することをお勧めします。 不明な場合は、英語の言語フィールドの場合、10
のmaxGrams
値から開始することをお勧めします。Atlas Search は、特定の string に対して、
edgeGram
またはrightEdgeGram
トークン化よりもnGram
用のトークンを作成するため、nGram
トークン化戦略は避けます。
string
フィールドをオートコンプリートタイプとしてインデックスを作成する場合は、次の利点のために、フィールドを Atlas Search stringタイプとしてインデックスすることをお勧めします。
オートコンプリート演算子を使用すると、完全一致のスコアがブーストされます。 例については、「 Atlas Search でオートコンプリートを使用する方法 」チュートリアルの「 高度な例 」を参照してください。
オートコンプリート演算子とテキスト演算子などの string 検索をサポートする別の演算子を使用して、同じクエリ内の同じフィールドをクエリします。 例については、 「 複数のフィールドにわたる検索の例 」を参照してください。
埋め込みドキュメント
Atlas Search は、レプリカセットまたは単一のシャードで、パーティションごとに 2、100、000、000インデックスオブジェクトを超えるインデックスの変更の複製を停止します。ここでは、インデックス作成された各埋め込みドキュメントは1 つのオブジェクトとしてカウントされます。 embeddedDocuments
フィールド型を使用すると、この制限を超えるオブジェクトのインデックスが作成される可能性があり、そのためインデックスがStale
クエリ可能な状態に移行し、古い結果が生じる可能性があります。 インデックスオブジェクトが2.1 億を超えるコレクションに対して Atlas Searchインデックスを作成する場合は、numPartitions
オプションを使用するか、クラスターをシャーディングする必要があります。
インデックス オブジェクトの正確な数は、ドキュメントの変更と削除の速度によって異なる可能性があります。 Lucene Docs の検索最大数メトリクスは、レプリカセットまたはシャードごとのすべてのインデックスにわたるインデックス オブジェクトの現在の数の上限を提供します。 次の手順を実行することで、単一のインデックス内のインデックス オブジェクトの予想数を概算できます。
ドキュメントあたりのインデックス オブジェクトの数を計算します。 ネストの各レベルで、各埋め込みドキュメントは個別のインデックス オブジェクトとしてカウントされます。
total number of index objects = 1 + number of nested embedded documents ドキュメントあたりのインデックス オブジェクト数に、コレクション内のドキュメントの総数を掛けます
total number of index objects x total number of documents in collection
この近似値は下限があることに注意してください。
例
この チュートリアル で説明されている、 という名前の コレクション schools
と、そのコレクションに次のような1000 ドキュメントが含まれているとします。
{ "_id": 0, "name": "Springfield High", "mascot": "Pumas", "teachers": [ { "first": "Jane", "last": "Smith", "classes": [ { "subject": "art of science", "grade": "12th" }, ... // 2 more embedded documents ] }, ... // 1 more embedded document ], "clubs": { "stem": [ { "club_name": "chess", "description": "provides students opportunity to play the board game of chess informally and competitively in tournaments." }, ... // 1 more embedded document ], ... // 1 more embedded document } }
次に、 schools
コレクション内の次のフィールドのインデックス定義について考えてみましょう。
teachers
という名前のドキュメントの配列は、動的マッピングが有効になっているembeddedDocuments
タイプとしてインデックス付けされます。 ただし、 classes
フィールドは インデックスがありません。 以下を使用して、インデックス オブジェクトを計算します。
ドキュメントあたりのインデックス オブジェクトの数を計算します。
Number of ``teachers`` embedded documents = up to 2 Total number of index objects per document = 1 + 2 = 3 コレクション内のドキュメントの合計数を掛けます。
Number of documents in the collection = 1000 Number of index objects per document = 3 Total number of index objects for collection = 1000 x 3 = 3000
teachers
とteachers.classes
という名前のドキュメントの配列は、動的マッピングが有効になっているembeddedDocuments
タイプとしてインデックス付けされます。 以下を使用して、インデックス オブジェクトを計算します。
ドキュメントあたりのインデックス オブジェクト数を計算します。
Number of documents = 1 Number of ``teachers`` embedded documents = up to 2 Number of ``classes`` embedded documents = up to 3 Number of index objects per document = 1 + ( 2 x 3 ) = 7 コレクション内のドキュメントの合計数を掛けます。
Number of documents in the collection = 1000 Number of index objects per document = 7 Total number of index objects: 1000 x 7 = 7000
コレクションに、 2 、 100 、 000 、 000インデックス オブジェクトを生成する可能性のある大きな配列がある場合は、 embeddedDocuments
タイプのインデックスを含むクラスターをシャードする必要があります。
ファセット検索
同じフィールドを使用してデータをフィルタリングとファセットする場合は、次の Atlas Search タイプとしてフィールドをインデックスすることをお勧めします。
ファセットのために別のフィールドでデータをフィルタリングする例については、 「 Atlas Searchでファセットの使用方法 」チュートリアルを参照してください。
multi
アナライザ
multi
アナライザを使用して同じフィールドを複数の異なる方法で分析すると、特に非常に長い値を持つフィールドを分析する場合、インデックスが大きくなる可能性があります。
多言語検索
Atlas Search言語アナライザを使用して、多くの言語をインデックスできます。 Atlas Search が組み込みのアナライザを提供する言語のリストについては、言語アナライザを参照してください。 例については、 「 多言語 Atlas Search クエリの実行方法 」チュートリアルを参照してください。 現在組み込み言語アナライザのリストに含まれていない言語をインデックスしてクエリするには、カスタムアナライザを作成できます。 例については、「カスタム言語アナライザの例 」を参照してください。
コレクションに各言語のドキュメントが 1 つあるとします。 次の点を考慮してください。
言語アナライザを使用して、同じインデックス内でフィールドを個別にインデックス化できます。 単一のインデックスで、同じクエリで複数の言語をサポートできます。
あるいは、言語ごとにインデックスを作成することもできます。これは、異なる言語のドキュメントを分離するのに役立ちます。 各インデックスは変更ストリーム カーソルであるため、維持するにはコストが高くなる可能性があることに注意してください。
親ドキュメント内に言語ドキュメントがネストされている場合は、単一のインデックスを作成できます。 ただし、インデックス定義のペイロードが大きくなり、クエリが複雑になる場合があります。
これらのデータモデルとインデックス定義の詳細については、 MongoDB Blogを参照してください。
シノニム コレクション
シノニム ソース コレクションへの挿入とアップデートは、シノニム ソース コレクションが小さい場合にのみ高速です。 最高のパフォーマンスを得るには、シノニム(同意語)ソース コレクションへの挿入とアップデートをバッチすることをお勧めします。
シノニム(同意語)マッピングの定義には、 データベース内のシノニム コレクションによって使用されるディスク領域とは別に、追加のディスク領域は必要ありません。 ただし、シノニム(同意語)マッピングではメモリにアーティファクトが作成されるため、多くのドキュメントを含むシノニム コレクションでは、Atlas Search によりより多くのメモリを占有するアーティファクトが作成されます。
検索する メモリ管理
Atlas Search はファイルシステムキャッシュと JVM ヒープメモリの両方を使用します。クエリを処理および追跡するために、インデックス作成や検索操作中に使用されるクエリオブジェクト、サーチャーオブジェクト、その他の一時データなどのさまざまなオブジェクトをJVMヒープに格納します。セグメントファイルや辞書ファイルなどのメモリマップファイルをファイルシステムのキャッシュに保存し、特にインデックスファイルを読み込む際のパフォーマンスを向上させます。
mongod
プロセスと mongot
プロセスの両方が同じノードで実行されるデプロイメントでは、mongod
に割り当てられるメモリはクラスター階層に基づいて変わります。
M40
以上の階層のクラスターでは、mongod
は物理 RAM の50% 以上を WiredTiger キャッシュに専用し、残りのメモリはメモリ内操作、基礎となるオペレーティングシステム、およびその他のシステムサービス用に予約されます。M30
以下の階層クラスターの場合、mongod
は物理 RAM の 25% を WiredTiger キャッシュに割り当てます。
したがって、mongot
に割り当てられたメモリは、総RAMの一部であり、メモリだけでなく、CPUやディスクIOにおいても、mongod
とmongot
の間でリソース競合の問題が発生する可能性があります。
mongot
プロセスが別の検索ノードで実行されるデプロイメントでは、Atlasは使用可能なRAMの一部をJVMヒープに割り当て、監視やオートメーションなどのプロセスに少量のメモリを使用し、残りのメモリは検索に利用可能です。
検索インデックスが大きく、使用可能なメモリが少ない場合、メモリ不足によりインデックス作成やクエリ中にパフォーマンスが低下する可能性があります。任意のキーを持つドキュメントのインデックスで動的マッピングを有効にすると、検索インデックスが大きくなる可能性があります。これにより、マッピングの爆発が発生する可能性があります。mongot
による過剰なメモリ消費は、mongot
がOOMを実行する原因となり、mongot
がクラッシュする可能性もあります。
次のメトリクスを使用して、mongot
がOOM を実行中かどうかを判断できます。
Search Page Faults
とDisk IOPS
の数の増加。これは、OS がディスクから必要なページを取得し続け、それらをRAMに読み込む場合に発生します。Normalized Process/System CPU
とIOWait
のレベルが上昇すると、パフォーマンスが低下する可能性があります。
本番環境向けのアプリケーションには、専用の検索ノードへの移行をお勧めします。メモリが不足するとパフォーマンスの問題が発生する可能性があるため、検索ノードのサイズを適切に調整することが重要です。
Atlas Search インデックスの作成と更新
Atlas Search インデックスの作成は、リソースを集中的に消費します。 インデックスの構築中に Atlas クラスターのパフォーマンスが影響を受ける可能性があります。
Atlas はコレクションに対するすべての書込み (write) を複製します。 つまり、Atlas Search インデックスを持つコレクションごとに、書込み (write) は、そのコレクションに定義されている Atlas Search インデックスの量に複製されます。
場合によっては、Atlas Search インデックスを再構築する必要がある場合があります。 Atlas Search インデックスの再ビルドもリソースを消費するため、データベースのパフォーマンスに影響を与える可能性があります。 Atlas Search は、次の場合にのみインデックスを自動的に再ビルドします。
注意
Atlas Search はダウンタイムなしのインデックス作成をサポートしているため、Atlas Search がインデックスを再構築している間も検索クエリを実行し続けることができます。 Atlas Search は、新しいインデックスの構築中も古いインデックスを最新状態に維持します。 この操作には、古いインデックスで使用されているディスク領域の 125% に相当する空きディスク領域を割り当てることをお勧めします。 インデックスによって現在使用されているディスク領域の量は、「 使用済みディスク領域の検索 」メトリクスで確認できます。
ディスク容量が不足していてインデックスの再構築が失敗した場合は、需要の増加に対応するためにクラスターの容量を一時的に拡張することをお勧めします。 「ストレージの問題の修正 」で説明されているように、オートスケーリングが有効になっているクラスターでも、この変更を手動で行うことができます。
別個の検索ノードを配置した場合、Java 21 アップグレード などの特定の変更に対して、Atlas はインデックスの再構築中に自動的に追加の検索ノードを配置するため、追加の空きディスク領域を割り当てる必要はありません。Atlas は、インデックス定義に変更が加えられたためにインデックスを再構築ことになっても、追加の検索ノードを配置しません。
Atlas Search がインデックスを再ビルドすると、ユーザー側から追加のアクションがなくても、古いインデックスが自動的に置き換えられます。
結果整合性とインデックス作成レイテンシ
Atlas Search は 結果整合性 をサポートしており、より強力な整合性保証は提供しません。 つまり、MongoDB コレクションに挿入され、Atlas Search によってインデックスが作成されたデータは、 $search
クエリですぐに使用できなくなります。
Atlas Search は MongoDB Change Stream からデータを読み取り、そのデータを非同期プロセスでインデックスを作成します。 このプロセスは通常非常に高速ですが、レプリケーションのレイテンシ、システムリソースの可用性、インデックス定義の複雑さによって影響を受ける場合があるかもしれません。 Atlas Search インデックスの数が多いと、Atlas Search インデックスのレプリケーションラグとレイテンシにも影響する可能性があります。
ドキュメント マッピングの説明
Atlas Search が任意のキーを持つドキュメントをインデックス化し、動的マッピングがある場合、マッピングの急増が発生します。 mongot
プロセスはメモリを消費する量が増加し、クラッシュする可能性があります。 インデックスにフィールドを追加しすぎると、マッピングが急増する可能性があります。 この問題に対処するには、クラスターをアップグレードするか、データ内のすべてのフィールドにインデックスを作成しない静的マッピングを使用します。
ワイルドカード パスを使用してフィールドを検索する場合は、チュートリアルのようなスキーマを使用するように検索を設計します。 キーと値のスキーマを使用するワイルドカード パス検索を実行すると、Atlas Search は各キーを独自のフィールドとしてインデックス化するため、マッピングが急増する可能性があります。
例
キーと値のスキーマの例は次のとおりです。
ruleBuilder: { ruleName1: <data>, ruleName2: <data>, ..... ruleName1025: <data> }
チュートリアルのようなスキーマを使用するように再構成された同じデータの例は、次のとおりです。
{ ruleBuilder: [ {name: ruleName1, data: <data>}, {name: ruleName2, data: <data>}, ... {name: ruleName1025, data: <data>} ] }
ソース フィールドの保存
Atlas Search に保存するフィールドを構成すると、 $sort
、 $match
、 $group
、 $skip
など、後続の 集計パイプライン ステージ のパフォーマンスが向上します。 元のドキュメントと一致したデータセットが大きくなり、データ全体を検索するのが非効率的になる場合は、この最適化を使用します。 Atlas Search に特定のフィールドを保存し、保存されたフィールドのみを返す方法の詳細については、「 Atlas Search インデックスに保存されたソース フィールドの定義 」と「 保存されたソース フィールドの返却 」を参照してください。
後続のステージに必要な最小限の数のフィールドのみを保存することをお勧めします。 必要に応じて、パイプライン ステージの最後に$lookup
を使用して、例に示すようにドキュメント全体を検索できます。 不要なフィールドを保存すると、ディスク使用率が向上し、インデックス作成やクエリ中に悪影響が及ぶ可能性があります。
スケーリングに関する考慮事項
Atlas Search のアップグレード
Atlas Search は Atlas クラスターに配置されます。 Atlas Search の新しいバージョンを配置すると、Atlas クラスターで短時間のネットワーク障害が発生し、クエリ結果が返される可能性があります。 配置中に問題を軽減し、アプリケーションへの影響を最小限に抑えるには、次の点を考慮してください。
アプリケーションに再試行ロジックを実装します。
AtlasメンテナンスWindowsを構成します。
注意
Atlas Search のアップグレードは、メンテナンスウィンドウ中にのみ開始され、メンテナンスウィンドウ後に継続される可能性があります。
各リリースの変更の詳細については、「 Atlas Search の変更ログ 」を参照してください。
インデックス作成パフォーマンスのスケールアップ
クラスターをより多くのコアを持つ上位階層にアップグレードすることで、Atlas Search インデックスの最初の同期と定常状態のインデックスをスケールアップできます。 Atlas Search は、使用可能な全コアの割合を使用して最初の同期と定常状態のインデックス作成の両方を実行し、クラスターをアップグレードすることで新しいコアが使用可能になるにつれてパフォーマンスが向上します。
Atlas クラスター構成の変更
ローカルNVMe storageタイプを使用するようにデプロイメントを再構成するか、NVMe storageベースのクラスターをアップスケールする場合、各ノードが基礎の構成またはアップスケールのアクションを完了した後、Atlas Search はすべての構成済みAtlas Search検索インデックスの最初の同期を実行します。Atlas Search インデックスの最初の同期がクラスター構成変更の完了に要した時間を超える場合、Atlas クラスター内のすべてのノードで最初の同期が完了するまで$search
クエリを実行することはできません。
Atlas クラスターと ワークロードを個別にスケーリングするには、$search
専用の検索ノード を配置することをお勧めします。専用検索ノードはmongot
プロセスのみを実行するため、 mongot
プロセスの可用性、パフォーマンス、ワークロードのバランスが向上します。