マルチテナント SaaS データベース テナント パターン
適用対象: Azure SQL データベース
この記事では、マルチテナント SaaS アプリケーションに使用できるさまざまなテナント モデルについて説明します。
マルチテナント SaaS アプリケーションを設計するときは、アプリケーションのニーズに最適なテナント モデルを慎重に選択する必要があります。 テナント モデルでは、各テナントのデータをストレージにマップする方法を決定します。 選択したテナント モデルは、アプリケーションの設計と管理に影響します。 後で別のモデルに切り替えると、高コストになる場合があります。
A. SaaS の概念と用語
サービスとしてのソフトウェア (SaaS) モデルでは、会社はソフトウェアの "ライセンス" を販売しません。 代わりに、各顧客は会社にレンタル料金を支払って、会社の "テナント" になります。
レンタル料金の支払いと引き換えに、各テナントは、SaaS アプリケーションのコンポーネントにアクセスし、データを SaaS システムに保存できるようになります。
"テナント モデル" という用語は、テナントが保存するデータの編成方法を指します。
- シングル テナント: 各データベースには、1 つのテナントからのデータだけが格納されます。
- マルチテナント: 各データベースには、複数の異なるテナントからのデータが (データのプライバシーを保護するメカニズムを使って) 格納されます。
- ハイブリッド テナント モデルも利用できます。
B. 適切なテナント モデルを選択する方法
一般に、テナント モデルがアプリケーションの機能に影響を及ぼすことはありませんが、ソリューション全体の他の側面に影響を与えることがあります。 次の条件は、各モデルの評価に使用されています。
拡張性:
- テナントの数
- テナントごとのストレージ
- 集計でのストレージ
- ワークロード
テナントの分離: データの分離とパフォーマンス (1 つのテナントのワークロードが他のテナントに影響を及ぼすかどうか)。
テナントあたりのコスト: データベースのコスト
開発の複雑さ:
- スキーマへの変更
- クエリへの変更 (パターン別に必要)
運用の複雑さ:
- パフォーマンスの監視と管理
- スキーマ管理
- テナントの復元
- ディザスター リカバリー
カスタマイズ性: テナント固有またはテナント クラス固有どちらかの、サポートされるスキーマ カスタマイズの容易性
テナントの説明ではデータ レイヤーに着目していますが、 アプリケーション レイヤーについて少し検討してみましょう。 アプリケーション レイヤーは、モノリシック エンティティとして扱われます。 アプリケーションを多数の小規模コンポーネントに分割した場合、選択したいテナント モデルが変わる可能性もあります。 テナントと使用するストレージ テクノロジ/プラットフォームの両方に関して、一部のコンポーネントを他のコンポーネントとは別に扱うこともできます。
C. シングルテナント データベースを利用したスタンドアロンのシングルテナント アプリ
アプリケーション レベルの分離
このモデルでは、アプリケーション全体がテナントごとに 1 回ずつ、繰り返しインストールされます。 アプリの各インスタンスはスタンドアロン インスタンスなので、他のスタンドアロン インスタンスとやり取りすることはありません。 アプリの各インスタンスにはテナントが 1 つしかないため、データベースも 1 つしか必要ありません。 テナントのデータベースは、そのテナント専用です。
各アプリ インスタンスは、別個の Azure リソース グループにインストールされます。 ソフトウェア ベンダーまたはテナントのいずれかがリソース グループを所有するサブスクリプションを所有することができます。 どちらの場合も、ベンダーはテナントに対してソフトウェアを管理できます。 各アプリケーション インスタンスは、そのインスタンスに対応するデータベースに接続するように構成されます。
各テナント データベースは単一データベースとしてデプロイされます。 このモデルでは、最大限のデータベースの分離を提供しています。 しかし、ピーク時の負荷を処理できる十分なリソースが各データベースに割り当てられていることが、分離の要件になります。 そこで、異なるリソース グループまたは異なるサブスクリプションにデプロイされているデータベースに対して、Elastic Pool は使用できないことが問題になります。 この制約によって、このようなスタンドアロン シングルテナント アプリのモデルは、データベース全体のコストの観点では、最も高コストなソリューションになります。
ベンダーの管理
アプリ インスタンスが別のテナント サブスクリプションにインストールされていても、ベンダーはすべてのスタンドアロン アプリ インスタンスの全データベースにアクセスできます。 アクセスは、SQL 接続経由で行われます。 このクロス インスタンス アクセスによって、ベンダーはスキーマ管理やレポートまたは分析を目的としたデータベース間のクエリを一元化できます。 このような一元管理が求められている場合、データベースの Uniform Resource Identifier (URI) にテナント識別子をマップするカタログがデプロイされている必要があります。 Azure SQL Database には、カタログを提供するために共に使用されるシャーディング ライブラリが用意されています。 シャーディング ライブラリは、正式には "Elastic Database クライアント ライブラリ" といいます。
D. テナント単位データベースを利用したマルチテナント アプリ
この次のパターンでは、多数のデータベースを備えたマルチテナント アプリケーションを使用します。各データベースはすべて、シングルテナント データベースです。 新しいデータベースは、新しいテナントごとにプロビジョニングされます。 アプリケーション層は、ノードごとにリソースを追加すると、垂直方向に拡大します。 また、ノードを追加すると、アプリは水平方向に縮小します。 拡大/縮小はワークロードに基づいており、個々のデータベースの数や大きさには依存しません。
テナントのカスタマイズ
スタンドアロン アプリ パターンと同様に、シングルテナント データベースを使用すると、テナントが強固に分離されます。 モデルにシングルテナント データベースのみを定義しているアプリでは、指定された任意の 1 つのデータベースに対応するスキーマを、そのテナント用にカスタマイズおよび最適化できます。 このカスタマイズは、アプリの他のテナントには影響しません。 おそらく、該当のテナントは、すべてのテナントで必要とされる基本的なデータ フィールド以外のデータを必要としています。 さらに、追加のデータ フィールドにはインデックスが必要です。
テナント単位データベースでは、1 つまたは複数の個別テナントに対するスキーマをカスタマイズすることが、目的達成への近道です。 アプリケーション ベンダーは、スキーマのカスタマイズを一括で慎重に管理するための手順を作成する必要があります。
エラスティック プール
同じリソース グループにデータベースをデプロイする場合、それらのデータベースをエラスティック プール内にまとめることができます。 プールは、多数のデータベース間のリソースの共有をコスト効率よく行う方法を提供しています。 このプールのオプションは、発生するピーク時の使用率に対応する十分な規模を各データベースが備えるよりも、低コストです。 プールされたデータベース共有からリソースにアクセスしても、高レベルでのパフォーマンスの分離を達成できます。
Azure SQL Database では、共有を構成、監視、および管理するために必要なツールを提供しています。 プールレベルとデータベースレベルの両方のパフォーマンス メトリックを、Azure portal で、または Azure Monitor ログ経由で使用できます。 メトリックは、集計とテナント固有両方のパフォーマンスに対して、優れた洞察を与えることができます。 個々のデータベースは、特定のテナントに対して予約済みのリソースを提供するために、プール間で移動できます。 これらのツールを活用すると、コスト効率の高い方法で優れたパフォーマンスを確保できます。
テナント単位データベースに対する操作のスケール
Azure SQL Database には、100,000 個を大きく超えるような多数のデータベースを一括で管理するために設計された、数多くの管理機能が用意されています。 これらの機能により、テナント単位データベース パターンの有用性が確保されます。
たとえば、1000 個のテナントを持つデータベースが、唯一のデータベースとしてシステムに搭載されているとします。 データベースが保持するインデックスの数を 20 とします。 1,000 個のシングルテナント データベースを保持するようにシステムが変換されると、インデックスの数は 20,000 に増加します。 Azure SQL Database では、自動チューニングの一環として、インデックスの自動作成機能が既定で有効になっています。 インデックスの自動作成では、20,000 個すべてのインデックスと進行中の create および drop の最適化を、ユーザーに代わって管理します。 自動化されたこれらのアクションは個々のデータベース内で実行され、他のデータベースでの類似のアクションによる調整や制限は受けません。 インデックスの自動作成では、ビジー状態のデータベースのインデックスをそれ以外のデータベースとは異なる方法で処理します。 仮にこの大がかりな管理タスクを手動で実行しなければならないとしたら、テナント単位データベースのスケールで、このようにインデックス管理をカスタマイズすることは難しいでしょう。
効果的なスケーリングを行う他の管理機能を次に示します。
- 組み込みのバックアップ
- 高可用性:
- ディスク上での暗号化
- パフォーマンス テレメトリ
オートメーション
管理操作は、DevOps モデルを使って、スクリプト化して提供できます。 操作を自動化して、アプリケーションに公開することもできます。
たとえば、単一のテナントを以前のポイント イン タイムまで自動的に復旧できます。 復旧するには、テナントを格納する 1 つの単一テナント データベースを復元するだけでかまいません。 この復元が他のテナントに影響を及ぼすことはなく、必ず個々のテナントごとに極めて詳細なレベルで管理操作が行われます。
E. マルチテナント データベースを使用したマルチテナント型のアプリ
利用可能な別のパターンとして、マルチテナント データベースに多数のテナントを格納する方法があります。 アプリケーション インスタンスは、任意の数のマルチテナント のデータベースを保持できます。 マルチテナント データベースのスキーマは、特定のテナントのデータを選択的に取得できるように、1 つまたは複数のテナント識別子列を必ず保持します。 さらに、スキーマでは、テナントのサブセットからのみ使用されるいくつかのテーブルまたは列が必要になることがあります。 ただし、静的コードと参照データは 1 回しか格納されず、すべてのテナントで共有されます。
テナントの分離が犠牲になる
データ: マルチテナント データベースでは必然的に、テナント分離が犠牲になります。 複数のテナントのデータが、1 つのデータベースに一緒に格納されます。 開発時には、クエリによって複数のテナントのデータを公開しないようにしてください。 SQL Database では、行レベルのセキュリティをサポートしています。これにより、1 つのクエリから返されるデータのスコープを強制的に単一のテナントにすることが可能です。
処理: マルチテナント データベースでは、全テナントでコンピューティング リソースおよびストレージ リソースが共有されます。 データベースが許容できる状態で実行されるように、データベース全体を監視できます。 ただし、Azure システムは、これらのリソースの使用を個々のテナントごとに監視または管理するための組み込みの方法を備えていません。 そのため、過稼働状態の 1 つのテナントのワークロードが、同じデータベース内の他のテナントのパフォーマンス エクスペリエンスに影響を及ぼすことで、マルチテナント データベースが "うるさい隣人" に遭遇するリスクは高まります。 追加のアプリケーション レベルの監視を使用すると、テナントレベルのパフォーマンスを監視できます。
低コスト
一般に、マルチテナント データベースは、テナント単位でのコストが最も低くなります。 単一データベースのリソース コストは、同じサイズのエラスティック プールより低くなります。 さらに、テナントが限られた 1 つのストレージしか必要としないシナリオでは、潜在的には何百万ものテナントが単一のデータベース内に格納される可能性があります。 エラスティック プールに何百万ものデータベースを保持することはできません。 しかし、1,000 個のプールを保持して、1 プールあたり 1,000 個のデータベースを含むソリューションでは、何百万単位の規模に達して管理が困難になる恐れがあります。
最も柔軟かつスケーラブルなシャード マルチテナント モデルを含め、マルチテナント データベース モデルによる 2 つの方法について、以下に説明します。
F. 単一のマルチテナント データベースを利用したマルチテナント型のアプリ
最も単純なマルチテナント データベース パターンでは、すべてのテナントのデータをホストする単一データベースを使用します。 追加されるテナントが増えると、ストレージおよびコンピューティング リソースが増大し、データベースは拡大されます。 拡大/縮小には限界がありますが、この拡大に対応できれば十分かもしれません。 しかし、その限界に達するずっと前に、データベースの管理が困難になります。
個々のテナントに重点を置いた管理操作は、マルチテナント データベースでの実装がより複雑になります。 そして、一括して行う場合は、許容できないほどにこれらの操作が遅くなる恐れがあります。 例として、1 つのテナントだけに対するデータのポイント イン タイム リストアがあります。
G. シャード マルチテナント データベースを利用したマルチテナント型のアプリ
ほとんどの SaaS アプリケーションでは、一度に 1 つのテナントのデータにしかアクセスしません。 任意の 1 つのテナントに対するすべてのデータが 1 つのシャードに格納されている場合、このアクセス パターンによって、複数のデータベースまたはシャード間にテナント データを分散させることができます。 マルチテナント データベース パターンと組み合わせると、シャード モデルによってほぼ無限の拡大/縮小が可能になります。
シャードの管理
シャーディングは、設計および運用管理の両方をより複雑にします。 テナントとデータベース間のマッピングを維持するために、カタログが必要になります。 さらに、シャードとテナントの入力を管理するための管理手順が必要になります。 たとえば、シャードの追加と削除、およびシャード間でのテナント データの移動の手順が作成される必要があります。 拡大/縮小するための 1 つの方法は、新しいシャードを追加して、新しいテネントを入力することです。 また、別の方法として、入力密度の高いシャードをより入力密度の低い 2 つのシャードに分割することもできます。 複数のテナントが移動または停止された後は、入力が少ないシャードを統合することもできます。 統合によって、リソース活用のコスト効率が高まります。 また、ワークロードを分散させるために、シャード間でテナントが移動される場合もあります。
SQL Database は、シャーディング ライブラリとカタログ データベースで動作する分割/マージ ツールを提供しています。 提供されているアプリを使って、シャードを分割およびマージでき、シャード間でテナント データを移動できます。 また、アプリでは、影響を受けたテナントを移動する前にオフラインとしてマークすることで、これらの操作時にカタログを維持することもできます。 移動後、アプリはもう一度、新しいマッピングでカタログを更新し、テナントのマーキングをオンラインに戻します。
より管理しやすい小規模なデータベース
シャード マルチテナント ソリューションでは、複数のデータベースにテナントを分散させることで、より管理しやすい小規模なデータベースになります。 たとえば、特定のテナントのポイント イン タイム リストアでは、すべてのテナントを含む大規模なデータベースではなく、より小規模な単一のデータベースをバックアップから復元します。 ワークロードと管理の手間のバランスを取るために、データベース サイズと、データベースごとのテナント数を選ぶことができます。
スキーマ内のテナント識別子
使用されるシャーディングの手法に応じて、データベース スキーマに追加の制約が適用される場合があります。 SQL Database の分割/マージ アプリケーションでは、スキーマにシャーディング キーが含まれている必要があります。このキーは通常、テナント識別子です。 テナント識別子は、シャード化されたすべてのテーブルの主キー内にある最初の要素です。 テナント識別子によって、分割/マージ アプリケーションは、特定のテナントに関連付けられたデータを迅速に検索して移動できます。
シャードのエラスティック プール
シャード マルチテナント データベースは、Elastic Pool 内に配置できます。 一般に、プール内に多数のシングルテナント データベースを保持すると、少数のマルチテナント データベース内に多数のテナントを保持する場合と同じくらい、コスト効率が高まります。 比較的非アクティブなテナントの数が多い場合、マルチテナント データベースが便利です。
H. ハイブリッドのシャード マルチテナント データベース モデル
ハイブリッド モデルでは、すべてのデータベースがスキーマ内にテナント識別子を保持します。 データベースはすべて、複数のテナントを格納できると共に、データベースのシャード化が可能です。 そのため、スキーマ検出では、すべてマルチテナント データベースになります。 実際には、これらのデータベースの中にはテナントを 1 つしか含んでいないものもありますが、 関係ありません。特定のデータベースに格納されているテナント数が、データベース スキーマに影響を与えることはありません。
テナントの移動
特定のテナントを独自のマルチテナント データベースにいつでも移動できます。 また、考えが変われば、複数のテナントを含む 1 つのデータベースにそのテナントをいつでも戻すことができます。 新しいデータベースをプロビジョニングするときに、新しいシングルテナント データベースにテナントを割り当てることも可能です。
識別可能なテナント グループでリソースの必要性に大きな差異がある場合は、ハイブリッド モデルが最適です。 たとえば、無料評価版に参加しているテナントでは、サブスクライブしているテナントと同等の高いパフォーマンス レベルが保証されないと考えられます。 無料評価版のフェーズにあるテナントは、すべての無料評価版のテナント間でシャード化された 1 つのマルチテナント データベースに格納されるよう、ポリシーで規定されている場合もあります。 無料評価版のテナントが基本サービス層にサブスクライブされると、そのテナントは、テナント数がより少ない別のマルチテナント データベースに移動できます。 Premium サービス レベルの契約を結んでいるサブスクライバーは、独自のシングルテナント データベースに移動できます。
プール
このハイブリッド モデルでは、テナントごとのデータベース コストを削減するために、サブスクライバーのテナント用の単一テナント データベースをリソース プールに配置できます。 これは、テナント単位データベース モデルでも実行できます。
I. テナント モデルの比較
以下の表に、主なテナント モデル間の違いをまとめています。
Measurement | スタンドアロン アプリ | テナント単位データベース | シャード マルチテナント |
---|---|---|---|
スケール | 中 (1 ~ 100 秒) | 高 (1 ~ 100,000 秒) | 無制限 (1 ~ 1,000,000 秒) |
テナントの分離 | 高 | 高 | 低。シングル テナント (MT データベース内で単独) を除く。 |
テナントごとのデータベース コスト | 高。ピーク時のサイズ | 低。プールが使用される | 最低。MT データベースにある小規模テナントの場合。 |
パフォーマンスの監視と管理 | テナント単位のみ | 集計およびテナント単位 | 集計。ただし、シングルの場合のみテナント単位。 |
開発の複雑さ | 低 | 低 | 中。シャーディングに起因 |
操作の複雑さ | 低 ~ 高。 個別の場合は単純、一括の場合は複雑 | 低 ~ 中。 一括の場合はパターンで複雑さに対応 | 低 ~ 高。 個々のテナント管理が複雑 |