MongoDB Search でマルチテナンシーを実装すると、アプリケーションの 1 つのインスタンスが複数のテナントにサービスを提供できます。このページでは、 テナント分離を維持しつつ安全に増やすするようにデータとMongoDB Search インデックスを構築するための、 MongoDB Search に特に適用される設計に関する推奨事項について説明します。
重要
このガイダンスでは、単一の VPC内でテナントをコロケーションできることを前提としています。厳密なネットワーク分離が必要な場合は、テナントごとに個別のプロジェクトを維持する必要があります。
戦略の選択
分離ニーズ、スケーリング目的、書込み負荷要件に基づいて戦略を選択します。最も一般的な戦略は次のとおりです。
すべてのテナントに単一のコレクション(推奨)
すべてのテナント戦略に 1 つのコレクションを適用することをお勧めします。このアーキテクチャでは、すべてのテナント データを単一のデータベース内の 1 つのコレクションに保存します。各ドキュメント内にtenant_id フィールドを含めることで、テナントを区別できます。このフィールドは、UUID やテナント名など、テナントの一意の識別子にすることができます。
この集中型アプローチには、以下の利点があります。
インデックスの数を減らします
すべてのテナント データは 1 つのコレクションに保存されるため、必要なインデックスは1 つだけで、すべてのテナントのドキュメントを提供します。クラスターリソースの制限に達しないようにします。例には、
tenant_idおよびその他の共有フィールドまたはテナント固有のフィールドを 1 つのインデックスに含めることができます。メンテナンス操作を簡素化
すべてのデータを保存するコレクションが1 つだけであるため、複数のコレクションを保持したり、複数のデータベースにまたがってリソースを増やす必要はありません。また、単一のデータベース内の 1 つのコレクションのみを対象とする必要がある場合は、バックアップ、シャーディング、およびレプリケーション操作も簡素化します。
クエリを効率的に処理します
句内で と等価演算子を使用して、クエリに
tenant_idフィールドをフィルターとして指定します。$search.compound.filter注意
クエリ結果には、一致するテナントのドキュメントのみが含まれるため、テナント間でのデータの流出を防ぎます。
共存するテナントが同様のアクセス パターンとリソースサイズを共有する場合、この戦略は Luceneインデックスフィールド数も低く維持します。
重要
すべてのテナントの書込み負荷が高い場合、すべてのテナントを単一のコレクションに共存させると、書込み競合が発生する可能性があります。そのシナリオでは、書込み (write) 負荷をより基礎となるリソース全体に分散できるように、最も書込み (write) が最も多いテナントを個別のコレクションに分割することを検討してください。
独自のリソースページまたはインデックス作成要件を持つ大規模なテナントがある場合は、 ビュー を使用します。
テナントを分離します。 と
$match$expr操作を使用してビューを作成し、テナントのドキュメントのみをフィルタリングします。インデックスは個別に作成されます。ビューでMongoDB Searchインデックスを作成します。
そのため、他のテナントが使用する共有インデックスに影響を与えずに、大規模なテナントのインデックス定義をカスタマイズできます。他のすべてのテナントは 1 つのインデックスを使用できます。
クラスターあたり 2500 インデックスを超えると、基本クラスターに高負荷が発生し、データベースワークロードが中断されるリスクがあるため、推奨はされません。
現在、テナントごとに 1コレクション戦略を適用している場合は、多数のインデックスによるリソース競合によってレプリケーションラグの OOM エラーが増加するのを防ぐために、基本階層をスケールアップすることをお勧めします。また、すべてのテナント戦略に 1 つのコレクションに移行することも推奨しています。
高書込み (write) テナントの処理
特定のテナントの書込み (write) 負荷が大きい場合、 共有コレクションの競合が発生する可能性があります。 I/O 負荷を分散するために、最もボリュームのあるテナントのみを個別のコレクションに移動することをお勧めします。
一意の要件の処理(ビュー)
テナントに一意なインデックスが必要な場合、またはテナントが他のテナントよりも大幅に大きい場合は、 MongoDBビューを使用します。
$matchそのテナントのドキュメントのみをフィルタリングする 。そのビューでMongoDB Searchインデックスを作成します。これにより、過半数が使用する 共有インデックスを中断することなく、アウトバウンド テナントをカスタマイズできます。
テナントごとに 1 つのデータベース
テナントごとのデータベース設定では、各テナントに独自のデータベースが含まれます。この設定はテナント データを分離しますが、クラスター内のインデックスの数も乗じます。各テナントに多くのインデックス付きフィールドがある場合、クラスターは 2500-インデックス上限に達する可能性があります。
警告
インデックス数が高いと、ベース クラスターに大きな負荷が発生し、ワークロードが中断される可能性があります。クラスターを安定して保つには、インデックスの数を慎重に監視し、合計が 2500 インデックスを超えないようにします。
テナントごとに 1 つのコレクション(非推奨)
コレクションごとのテナント戦略は、各テナントを 共有データベース内の独自のコレクションにマッピングします。コレクションごとにインデックスを維持するオーバーヘッドによって、次の原因が発生する可能性があります。
レプリケーションラグの増加
リソース競合による OOM エラー
基本階層の不安定
テナントが非常に予測可能で軽量なワークロードでない限り、 MongoDB Search ではこの戦略は推奨されません。現在この戦略を使用している場合は、すべてのテナントに対して 1 つのコレクション戦略に移行してください。
インデックス付きフィールドの管理
インデックス フィールドを管理する際には、以下の推奨事項を考慮してください。
属性パターンを使用してテナントごとに異なるキーを保存する場合は、次の操作を行うことをお勧めします。
ビューを使用して、ドキュメントの埋め込み配列をフラット化します。
ディスクに保存されているMongoDB Searchインデックスをビューで作成します。
ドキュメントの配列をフラット化しない場合は、 embeddedDocuments 演算子クエリ($elemMatch と同様)を使用して属性をクエリする必要があります。これは、フラット化された構造をクエリするよりもパフォーマンスが低くなります。