Amazon Web Services ブログ

Amazon OpenSearch Service にマルチテナント SaaS のデータを格納する

この記事は、AWS SaaS ファクトリーのマネージャー、パートナーソリューションアーキテクトの Madhukar Thumma と、AWS SaaS ファクトリーのシニアパートナーソリューションアーキテクトである Ujwal Bukka によって執筆されました。

Amazon OpenSearch Service は、さまざまなユースケースにおいて、software-as-a-service (SaaS) プロバイダーによく利用されています。ただし、Amazon OpenSearch Service をマルチテナント環境で使用する場合、ソリューションのパーティション分割、分離、デプロイ、管理方法などに関して追加で幾つかの考慮すべき事項が出てきます。

OpenSearch Service クラスターを、絶えず変化するワークロードに合わせて、効果的にスケーリングする方法を検討する必要があります。ティアリングやノイジーネイバーがパーティショニングモデルにどのように影響するかを考えなければなりません。

この記事では、このような一般的なマルチテナントにおける問題に対処するために使用される戦略とパターンについて説明します。Amazon OpenSearch Service の構成要素を利用した、各テナントのデータ表現と、分離を行うために使用される具体的なモデルを見ていきます。

マルチテナントシステムにおけるデータ分割モデル

マルチテナントデータを任意のデータベースに保存することを検討するときは、テナントデータをどのように分割するかを考えます。マルチテナントシステムで使用される一般的なデータ分割モデルには、サイロ、プール、ハイブリッドの 3 つがあります。選択するモデルは、ソリューションのコンプライアンス、ノイジーネイバー、運用、および分離の要件によって異なります。

サイロモデル

コンプライアンス、規制、またはデータ分離の要件により、テナントがデータとリソースを他のテナントから分離したい場合に、このモデルを選択できます。このような場合は、テナント専用のリソースセットを個別に作成します。

サイロモデルでは、テナントデータが混在しない個別のストレージに各テナントのデータを格納します。Amazon OpenSearch Service を使用してサイロモデルを実装する方法は複数あります。サイロオプションの詳細は次のとおりです。

  • テナントごとのドメイン: OpenSearch Service でサイロモデルを実装するには、テナントごとに個別のドメイン (OpenSearch クラスターと同義) を設定します。各テナントを独自のドメインに配置することで、データを単独の構成にすることによるすべてのメリットが得られます。このアプローチは、あるテナントが他のテナントの体験に悪影響を及ぼす負荷をかける可能性があるノイジーネイバーなどの問題に自然に対処する方法を提供します。テナントごとにドメインを構築することには強みがありますが、管理やアジリティの課題も伴います。このモデルは分散型であるため、すべてのテナントとテナントのアクティビティの運用状態を集約して評価することが難しくなります。また、導入もより困難になります。各ドメインのクラスターのスケールアップやスケールダウンなどの更新は、各ドメインに個別に適用する必要があります。オンボーディングの際には、各テナントをシステムに追加するときに個別のドメインをプロビジョニングする必要があります。
    SaaS-Multi-Tenant-OpenSearch-1

    図 1 – テナントごとのドメインモデルにおけるデータアクセスフロー

    1. アプリケーションマイクロサービスはテナントからリクエストを受け取ります。
    2. このマイクロサービスでは、AWS Identity and Access Management (IAM) ロール と、テナント専用のドメインへのアクセスを制限するポリシーを使用できます。
    3. このマイクロサービスは、テナントの Amazon OpenSearch Service ドメイン情報を保持するデータベーステーブルをクエリし、そのテナント専用の OpenSearch Service ドメインにリクエストを送信して、要求された操作を実行できます。テナントに必要な権限がある場合、OpenSearch Service は要求された操作をインデックスに対して実行し、呼び出し元のマイクロサービスに結果を返します。
    4. 結果はクライアントに送り返されます。
  • テナントごとドメインモデルのサイロ型テナント分離: IAM ポリシーを、各テナントのデータを保持するドメインを分離するために使用します。これらのポリシーは、あるテナントが別のテナントのデータにアクセスすることを防ぎます。テナントごとにドメインを用意するサイロ分離モデルを実装するには、テナントリソースへのアクセスを制御するリソースベースのポリシーが作成できます。これは多くの場合、OpenSearch インデックスや API など、ドメインのサブリソースに対してプリンシパルが実行できるアクションを指定するドメインアクセスポリシーです。このドメインアクセスポリシーは、ドメインの「エッジ」でリクエストを許可または拒否します。要求が受け入れられると、きめ細かなアクセス制御の設定に基づいて、要求が評価され、認証されます。以下のコードスニペットは、「テナントごとのドメイン」サイロ戦略を実装する場合に、テナントをそれぞれのドメインに分離するために使用されるリソースベースのポリシーの例を示しています。「Principal」要素はテナントのロールを指定します。この例では「tenant-role-1」です。「Allow」は、「Tenant-1」に「tenant-1 ドメイン」上のサブリソースのみへのアクセス(es: esHttpGet、es: esHttpPost)の Get と Post を許可します。Resource 要素の末尾の「/*」は、このポリシーがドメイン自体ではなくドメインのサブリソースに適用されることを示しています。このポリシーが適用されると、テナントはこのドメインに制限されるだけでなく、新しいドメインを作成したり、既存のドメインの設定を変更したりすることもできなくなります。
    { 
        "Version": "2012-10-17", 
        "Statement": [ 
            { 
                "Effect": "Allow", 
                "Principal": { 
                    "AWS": "arn:aws:iam::123456789012:role/tenant-role-1" 
                }, 
                "Action": ["es:ESHttpGet","es:ESHttpPost"], 
                "Resource": "arn:aws:es:Region:account-id:domain/tenant-1/*" 
            } 
        ] 
    }
  • テナントごとのインデックス: テナントデータを Amazon OpenSearch Service ドメイン内の個別のインデックスに配置することで、テナントデータをサイロモデルで保存することもできます。この方法では、インデックスを作成して名前を付けるときにテナント識別子を使用します。インデックス名やクラスター名などのテナントインデックス情報を保持するデータベーステーブルを用意することをお勧めします。このデータベーステーブルがあると、テナントインデックスを柔軟に移動したり、テナントごとに複数のインデックスを作成したりできます。テナントごとのインデックスモデルでは、テナントごとに完全に独立したドメインを導入しなくても、サイロ化を達成できます。同時に、サイロが必要とする分離と、各テナントティアのインデックスのチューニングも可能です。この戦略はクラスター管理を簡素化し、多くの場合、マルチテナントシステムの全体的な俊敏性を向上させます。
    SaaS-Multi-Tenant-OpenSearch-2

    図 2 — テナントごとのインデックスモデルにおけるデータアクセスフロー

    図 2 は、テナントごとのインデックスモデルの基本的なフローを示しています。テナントごとのドメインモデルと比較すると、同じ Amazon OpenSearch Service ドメインでテナントごとにインデックスを作成します。

    パフォーマンス要件に基づいて、Amazon OpenSearch サービスドメイン用に作成できる OpenSearch インデックスの数に関する推奨事項があります。各 OpenSearch インデックスは 1 つ以上のシャードに分割されます。OpenSearch Service ドメイン内に作成できるシャードの総数は、クラスター内のノード数、ノードインスタンスサイズ、およびシャードサイズによって異なります。OpenSearch Service ドメイン内のシャードの総数は 30,000 未満に抑えることが推奨されており、Elasticsearch 7.x 以降ではノードあたり 1,000 シャードの制限があります。

    シャードの数とシャードのサイズは、OpenSearch Service ドメインのパフォーマンスに影響します。シャードサイズは、基盤となる OpenSearch Service インスタンスが処理できるほど小さくなければなりませんが、ハードウェアに不必要な負担をかけるほど小さくしないでください。このトピックの詳細については、シャードの数の選択 に関するAWSドキュメントを参照してください。

    これらの考慮事項を考慮し、OpenSearch Service ドメイン内に作成できるインデックスの数に上限を設けることができます。そのため、テナントごとのインデックスモデルは、テナントが何百、何千もある場合には適していない可能性があります。また、小規模なテナントの場合、テナントごとに専用のインデックスがあると、リソースの使用率が低下します。

  • テナントごとインデックスモデルのサイロ型テナント分離: IAM ポリシーを使用して、各テナントのデータを保持するインデックスを分離できます。「インデックスごとのテナント」サイロモデルのテナント分離を実装するには、この記事の以前のコードスニペットで定義したリソースポリシーを変更して、インデックス名を指定して「Tenant-1」を指定された 1 つまたは複数のインデックスに制限する必要があります。

    以下のコードは、「Tenant-1」を「tenant-index-1」インデックスのみに制限するサンプルリソースポリシーを示しています。

    { 
        "Version": "2012-10-17", 
        "Statement": [ 
            { 
                "Effect": "Allow", 
                "Principal": { 
                    "AWS": "arn:aws:iam::123456789012:role/tenant-role-1" 
                }, 
                "Action": ["es:ESHttpGet","es:ESHttpPost"],  
                "Resource": "arn:aws:es:Region:account-id:domain/test-domain/tenant-index-1/*" 
            } 
        ] 
    }

    ここで推奨されるアプローチは、OpenSearch Security プラグインがサポートする、きめ細かなアクセスコントロール (FGAC) を使用して、テナントを指定された 1 つまたは複数のインデックスに制限することで、テナントサイロモデルにおけるインデックスごとのテナント分離を実装することです。FGAC では、インデックス、ドキュメント、またはフィールドレベルで権限を制御できます (OpenSearch 6.7 以降)。IAM ユーザー/ロールまたは OpenSearch ユーザーを、必要な権限を持つ OpenSearch ロールにマッピングできるため、ロールマッピングによってこれを実現します。

    リクエストごとに、FGAC はユーザー認証情報を評価し、ユーザーを認証するか、リクエストを拒否します。FGAC がユーザーを認証すると、そのユーザーにマップされているすべてのロールを取得し、すべての権限を使用してリクエストの処理方法を決定します。

    テナントごとのインデックスサイロモデルで必要な分離を実現するには、FGAC のインデックス権限を利用して、特定のユーザー/ロールをテナントの特定のインデックスに制限できます。

プールモデル

自身のデータを他のテナントのデータと混在させて、共有リソースを利用しても問題ないテナントであれば、このモデルを選択できます。このモデルは管理オーバーヘッドを削減し、運用モデルを改善します。

プールモデルでは、すべてのテナントデータが (同じドメイン内の) 共有インデックスに保存されます。テナント識別子をデータ (ドキュメント) に導入することで、どのデータがどのテナントに属しているかを判断できます。

同じインデックス内でテナントデータが混在していると、サイロモデルに付属していた自然なテナント分離が失われます。これはアプリケーションのノイジーネイバープロファイルにも影響します。FGAC を使用してプールモデルで分離を実装できます。

図 3 — プールモデルのデータアクセスフロー

図 3 では、Amazon OpenSearch Service ドメインの下にプール化したインデックスが 1 つしか作成されておらず、プールされたインデックスの各ドキュメントに TenantID が追加されていることがわかります。Amazon OpenSearch Service は、リクエストオペレーションときめ細かなアクセス制御に基づいて、結果を制限します。

このアプローチを使用して何万ものテナントをオンボーディングする予定がある場合は、テナントドキュメントを含む複数のプールされたインデックスを持つことができる複数の Amazon OpenSearch Service クラスターにこのアプローチを拡張する必要があります。次に、プールされたインデックス名やクラスター名などのテナントインデックス情報を保持するデータベーステーブルを導入する必要があります。アプリケーションマイクロサービスはこのデータベーステーブルをクエリしてテナントインデックス情報を取得し、テナントリクエストをクラスタに転送できます。このクラスタには、テナントドキュメントが作成されるプールインデックスが格納されます。

プールモデルでのテナント分離: サイロモデルで使用されている IAM メカニズムでは、ドキュメントに保存されているTenantid に基づく分離を記述することはできません。テナント分離を実装するには、OpenSearch セキュリティプラグインでサポートされている FGAC を使用する必要があります。

プールモデルで必要な分離を実現するには、FGAC のドキュメントレベルのセキュリティを利用します。これにより、ロールをインデックス内のドキュメントのサブセットに制限できます。以下のコードのサンプルロールでは、クエリをテナント ID「Tenant-1」に制限しています。このロールを Tenant-1 に適用することで、分離を実現できます。

{
  "bool": {
    "must": {
      "match": {
        "TenantId": "Tenant-1"
      }
    }
  }
}

テナントがリソースを共有するプールモデルでは、テナントがデータとトラフィックの両方で増加するにつれて、あるテナントがすべてのリソースを消費し、他のテナントのパフォーマンスを低下させる、いわゆるノイジーネイバー問題に遭遇する可能性があります。この問題を解決するには、より大きなノードタイプのメモリと vCPU をクラスタに追加してスケールアップ (垂直スケーリング) するか、ノードを追加してスケールアウト (水平スケーリング) します。

共有プールインデックスのスケーリングメカニズムとして、インデックスエイリアス (1 つ以上のインデックスを指すことができる仮想インデックス名) を使用することもできます。共有プールインデックスのエイリアスを定義する必要があります。テナントが増えるにつれて、さらにインデックスが必要な場合は、このエイリアスの下に追加できます。

検討すべきもう 1 つのオプションは、テナントデータを再インデックスするか、テナントデータを独自のインデックスまたはドメインに移動することです。このオプションを実装するには、データベーステーブルを使用して、インデックス名、クラスター名、およびインデックスのテナントデータに対する読み取り/書き込み操作を許可または拒否する読み取り/書き込みフラグなどのテナントインデックス情報を保持できます。

アプリケーションがテナントデータにアクセスする場合、このテーブルをクエリしてテナントのインデックス名、そのインデックス名が属するクラスタ、読み取り/書き込みが有効/無効になっているかどうかを取得し、それに応じてリクエストをルーティング/許可できます。

テナントデータを再インデックスする場合は、書き込みフラグを無効にして読み取りのみを許可してから、ソーステナントのデータから別のインデックスまたは別のクラスターに再インデックスし、最後にテナントの新しいインデックス情報でデータベーステーブルを更新し、書き込みフラグを有効にします。書き込みフラグが無効になっている間に更新リクエストがあった場合は、そのリクエストをキューに入れて、書き込みフラグが有効になったら処理できます。このアプローチについて詳しく理解するには、このビデオを参照してください。

ハイブリッドモデル

サイロモデルとプールモデルを組み合わせたSaaSソリューションを見つけることは珍しくありません。同じ環境でサイロとプールを活用する方法とタイミングを左右する要因はいくつかあります。

一部の SaaS ソリューションでは、無料、スタンダード、プレミアムなど、テナントの各ティアに独自の体験を提供します。ハイブリッドモデルを使用して、各ティアに独自の体験を提供できます。たとえば、無料利用枠のテナントデータはすべて共有インデックス (プールモデル) に保存できますが、スタンダードティアのテナントはテナントごとのインデックスに合わせて調整し、プレミアムティアのテナントには独自のドメインを割り当てることができます。

SaaS-Multi-Tenant-OpenSearch-4

図 4 — ハイブリッドモデルのデータアクセスフロー

ハイブリッドモデルでのテナント分離: ハイブリッドモデルでは、サイロテナントの場合、前述のようにドメインアクセスポリシーや FGAC を使用してテナント分離を実装します。プールされたテナントについては、この記事の前半で説明したのと同じセキュリティプロファイルに従い、ドキュメントレベルで FGAC セキュリティモデルを使用してテナントを分離します。

この戦略はクラスター管理を簡素化し、俊敏性をもたらしますが、他の側面が複雑になります。たとえば、どのモデルを各テナントに関連付けるかを決定するコードがさらに複雑になります。

OpenSearch Dashboards

Amazon OpenSearch Service では、すべての OpenSearch Service ドメインに OpenSearch Dashboardsをインストールできます。OpenSearch Dashboards ではマルチテナントを実装できます。ダッシュボードのマルチテナントは、この記事で説明したデータテナントとは異なります。

OpenSearch Dashboards のテナントは、インデックスパターン、ビジュアライゼーション、ダッシュボード、その他の OpenSearch Dashboards オブジェクトを保存するためのスペースです。これらのテナントスペース内のオブジェクトへのアクセスを制御するには、FGAC を使用して、特定のクラスター権限、インデックス権限 (データを読み書きできるインデックスパターン)、およびテナント権限 (ビジュアライゼーション、ダッシュボード、その他の OpenSearch Dashboards オブジェクトを読み書きできるテナントパターン) を持つテナントのロールを定義できます。

このトピックに関する詳細については、OpenSearch Dashboards のマルチテナントに関する AWS ドキュメントを参照してください。Amazon OpenSearch Service では、OpenSearch Dashboards へのアクセスを制御するさまざまな方法を提供しています。OpenSearch Dashboards へのアクセスを制御する方法の詳細については、こちらをご覧ください。

まとめ

この記事では、Amazon OpenSearch Service を使用してマルチテナントソリューションを構築する際に考慮すべき重要な SaaS 戦略をいくつか紹介しました。

この記事で概説しているソリューションには、推奨される単一のモデルはないことに注意することが重要です。概説したバリエーションはそれぞれ、SaaS 設計に存在する自然な緊張感をいくらか浮き彫りにしています。パーティショニング戦略を選ぶ際には、完全に共有されたモデルのシンプルさと俊敏性と、より分離されたモデルによって提供されるセキュリティと可変性のバランスを取る必要があります。

Amazon OpenSearch Service は、一般的なパーティション分割モデルのそれぞれを実装するために必要なすべてのメカニズムをサポートしています。OpenSearch Service を深く掘り下げてみると、SaaS のコアバリューの多くとうまく一致していることがわかります。

翻訳はソリューションアーキテクトの福本が行いました。原文はこちらです。