Cloud Spanner でのマルチテナンシーの実装

このドキュメントでは、Cloud Spanner でマルチテナンシーを実装するさまざまな方法について説明しています。また、データ管理パターンとテナント ライフサイクル管理についても説明します。

マルチテナンシーは、ソフトウェア アプリケーションの単一のインスタンス(またはいくつかのインスタンス)で複数のテナントまたはお客様にサービスを提供する場合に使用します。このソフトウェア パターンは、単一のテナントまたは顧客から、数百または数千にまでスケーリングできます。このアプローチはクラウド コンピューティング プラットフォームにとって重要で、基盤となるインフラストラクチャは複数の組織で共有されます。

マルチテナンシーは、データベースなどの共有コンピューティング リソースによるパーティショニングの 1 つの手法であると考えられます。アパートのような建物のテナントに例えると、共有インフラストラクチャでありながら、専用のテナント スペースでもあるということです。マルチテナンシーは、Software-as-a-Service(SaaS)アプリケーションの一部です。

このドキュメントは、マルチテナント アプリケーションをリレーショナル データベースとして Spanner に実装するデータベース アーキテクト、データ アーキテクト、エンジニアを対象としています。このコンテキストを使用して、マルチテナント データを保存するさまざまな方法を説明します。マルチテナント アプリケーションにアクセスするエンティティを示すため、記事を通して「テナント」、「顧客」、「組織」という用語を一貫して使用します。

この記事では、Google Cloud にマルチテナント アプリケーションを実装する人事(HR)SaaS プロバイダを例として使用しています。この例では、HR SaaS プロバイダの複数の顧客がマルチテナント アプリケーションにアクセスする必要があります。このような顧客はテナントと呼ばれます。

Spanner は、リレーショナル データベース モデルのメリットと非リレーショナルの水平方向のスケーラビリティを兼ね備えた、Google Cloud のフルマネージド型、エンタープライズ クラス、分散型かつ整合性を備えたデータベースです。Spanner にはリレーショナル セマンティクスがあり、スキーマ、強制されたデータ型、強整合性、複数ステートメントの ACID トランザクション、ANSI 2011 SQL を実装する SQL クエリ言語を使用できます。

Spanner は、計画的なメンテナンスやリージョンの障害が発生した場合に、99.999% の可用性 SLA でゼロ ダウンタイムを実現します。高可用性とスケーラビリティにより、最新のマルチテナント アプリケーションがサポートされます。この記事では、Spanner でマルチテナンシーを実装するためのさまざまなアーキテクチャ アプローチについて説明します。

テナントデータ マッピング基準

マルチテナント アプリケーションでは、各テナントのデータが基盤となる Spanner データベースの複数のアーキテクチャ アプローチで分離されます。テナントのデータを Spanner にマッピングするために使用されるさまざまなアーキテクチャ アプローチの概要を次に示します。

  • インスタンス: テナントは 1 つの Spanner インスタンスにのみ存在します。そのテナント用のデータベースは 1 つのみです。
  • データベース: テナントは、複数のデータベースを含む 1 つの Spanner インスタンスのデータベースに存在します。
  • スキーマ: テナントはデータベース内の排他的なテーブルに存在し、複数のテナントを同じデータベースに配置できます。
  • テーブル: テナントデータは、データベース テーブルの行です。これらのテーブルは他のテナントと共有されます。

上記の基準はデータ管理パターンと呼ばれています。詳細はマルチテナンシーのデータ管理パターンセクションをご覧ください。上記の説明は次の基準に基づいています。

  • 分離: 複数のテナント間でのデータ分離の度合いは、マルチテナンシーの重要な考慮事項です。分離は、他のカテゴリの条件に対する選択項目によって決まります。たとえば、特定の規制やコンプライアンスの要件が分離の度合いに影響する場合があります。
  • アジリティ: インスタンス、データベース、テーブルの作成に関する、テナントのオンボーディングとオフボーディング作業の容易性を示します。
  • 運用: 一般的なテナント固有のデータベース オペレーションと管理作業(定期的なメンテナンス、ロギング、バックアップ、障害復旧など)の実装の可用性または複雑性を示します。
  • スケーリング: 将来の成長に対応できるシームレスな拡張性を示します。各パターンの説明には、そのパターンでサポートできるテナント数が示されています。
  • パフォーマンス: 各テナントへの排他的なリソースの割り当て、ノイジー ネイバー現象への対処、各テナントに対する予測可能な読み取りおよび書き込みパフォーマンスを行う機能。
  • 規制とコンプライアンス: リソースやメンテナンス オペレーションの完全な分離が必要となる、規制の厳しい業界や国の要件に対応する機能。たとえば、フランスの場合、データ保持要件として、個人識別情報はフランス国内にのみ物理的に保存される必要があります。

これらの基準に関連する各データ管理パターンについては、次のセクションで詳しく説明します。特定の一連のテナントに対してデータ管理パターンを選択する場合は、同じ基準を使用します。

マルチテナンシーのデータ管理パターン

以降のセクションでは、インスタンス、データベース、スキーマ、テーブルの 4 つの主要なデータ管理パターンについて説明します。

インスタンス

完全な分離を実現するため、インスタンスのデータ管理パターンでは、各テナントのデータを固有の Spanner インスタンスとデータベースに保存します。Spanner インスタンスには、1 つ以上のデータベースを含めることができます。このパターンでは、作成されるデータベースは 1 つのみです。前述の HR アプリケーションでは、顧客の組織ごとに異なる 1 つのデータベースを含む個別の Spanner インスタンスが作成されます。

次の図でわかるように、データ管理パターンではインスタンスごとに 1 つのテナントが対応しています。

インスタンスのデータ管理パターンでは、インスタンスごとに 1 つのテナントを保管します。

テナントごとに個別のインスタンスを用意するため、別々の Google Cloud プロジェクトを使用してテナントごとに異なる信頼境界を確立できます。また、各テナントのロケーション(リージョンまたはマルチリージョン)、ロケーションの柔軟性の最適化、パフォーマンスに基づいてインスタンス構成が選択できるというメリットがあります。

このアーキテクチャは、任意の数のテナントに簡単にスケーリングできます。SaaS プロバイダは、所定のリージョン内に任意の数のインスタンスを作成し、ハードリミットを設定できます。

次の表に、インスタンス データ管理パターンがさまざまな基準にどのように影響するかを示します。

条件 インスタンス - インスタンス データ管理パターンごとに 1 つのテナント
分離
  • 最高レベルの分離
  • 共有されるデータベース リソースはありません
アジリティ
  • オンボーディングとオフボーディングには次のセットアップまたはデコミッションが必要です。
    • Spanner インスタンス
    • インスタンス固有のセキュリティ
    • インスタンス固有の接続
  • オンボーディングとオフボーディングは Infrastructure as Code(IaC)によって自動化できます。
運用
  • テナントごとの独立したバックアップ
  • 分離された柔軟なバックアップ スケジュール
  • 運用上のオーバーヘッドが高い
    • 管理および維持のための多数のインスタンス(スケーリング、モニタリング、ロギング、パフォーマンス調整)
規模
  • スケーラビリティの高いデータベース
  • ノードの追加による無制限の拡張
  • テナントの数に制限はありません
  • 各テナントで使用可能な Spanner インスタンス
パフォーマンス
  • 個別のインスタンス内の各テナント
  • リソース競合なし
  • 各テナントに合わせたパフォーマンス チューニングとトラブルシューティング
規制要件とコンプライアンス要件
  • 特定のリージョンにデータを保存する
  • 企業や政府が求める特定のセキュリティ、バックアップ、監査プロセスを実装する

要約すると、重要なポイントは次のとおりです。

  • アドバンテージ: 最高レベルの分離ができる
  • デメリット: 運用上のオーバーヘッドが最も大きい

インスタンスのデータ管理パターンは、次のシナリオに最適です。

  • 異なるテナントが幅広いリージョンに分散しており、ローカライズされたソリューションが必要です。
  • 一部のテナントでは、規制やコンプライアンス要件により、非常に高度なセキュリティ プロトコルと監査プロトコルが求められます。
  • テナントのサイズは大きく異なります。大容量でトラフィックの多いテナント間でリソースを共有すると、競合や相互の機能低下が発生する可能性があります。

データベース

データベース データ管理パターンでは、各テナントは 1 つの Spanner インスタンスのデータベースの中に存在します。1 つのインスタンスに対して複数のデータベースを作成できます。テナント数に対してインスタンスが 1 つでは不十分な場合、複数のインスタンスを作成します。このパターンは、1 つの Spanner インスタンスが複数のテナントにより共有されることを意味します。

Spanner には、インスタンスあたり 100 データベースというハードリミットがあります。この上限により、SaaS プロバイダが 100 人を超えるユーザーにスケーリングする場合、プロバイダは複数の Spanner インスタンスを作成して使用する必要があります。

HR アプリケーションの場合、SaaS プロバイダは各テナントの作成および管理を、Spanner インスタンスの個別のデータベースで行います。

次の図に示すように、データ管理パターンではデータベースごとに 1 つのテナントがあります。

データベースのデータ管理パターンでは、データベースごとに 1 つのテナントを保管します。

データベースのデータ管理パターンでは、異なるテナントデータでデータベース レベルでの論理分離を実現します。ただし、これは単一の Spanner インスタンスであるため、すべてのテナント データベースが同一のリージョン構成と、同一の基盤となるコンピューティングとストレージの設定を共有します。

次の表で、データベースのデータ管理パターンがさまざまな基準にどのように影響するかを示します。

条件 データベース - データベースのデータ管理パターンごとに 1 つのテナント
分離
  • データベース レベルでの完全な論理分離
  • 基盤となる共有インフラストラクチャ リソース
アジリティ
  • データベースの作成または管理、および特定のセキュリティ管理を必要とする
  • IaC を介したオンボーディングとオフボーディングの自動化
運用
  • テナントごとの独立したバックアップ
  • 柔軟なスケジュール設定
  • インスタンス パターンと比較して運用上のオーバーヘッドが少ない
    • 最大 100 個のデータベースをモニタリングする 1 つのインスタンス
規模
  • スケーラビリティの高いデータベース
  • 無制限のインスタンス
  • 数千のノードを許可
  • インスタンスあたりのデータベース数は 100 個を上限とする
    • 100 テナントごとに新しい Spanner インスタンスを作成する
パフォーマンス
  • 複数のデータベース間でのリソースの競合
    • データベースが Spanner インスタンス ノードに分散
    • データベース共有インフラストラクチャ
  • パフォーマンスに影響を与えるノイジー ネイバー
規制要件とコンプライアンス要件
  • 特定のデータ所在地の規制要件を満たすため、ロケーション リージョンはインスタンス リージョンと一致する必要がある

要約すると、重要なポイントは次のとおりです。

  • アドバンテージ: より高レベルの隔離
  • デメリット: インスタンスあたりのテナント数に限りがある、ロケーションの柔軟性に欠ける

データベースのデータ管理パターンは、次のシナリオに最適です。

  • 複数のお客様が同一のデータ所在地(フランス、英国など)内に所在しており、同じ規制機関に属している場合。
  • テナントは、システムベースのデータ分離とバックアップ/復元を必要としますが、インフラストラクチャのリソース共有に適しています。

スキーマ

スキーマデータ管理パターンでは、単一のスキーマを実装する単一のデータベースが複数のテナントに使用され、各テナントのデータに別々のテーブルが使用されます。これらのテーブルを区別するには、テーブル名に tenant ID を接頭辞または接尾辞として含めます。

テナントごとに個別のテーブルを使用するデータ管理パターンは、前述のオプション(インスタンスとデータベースの管理パターン)と比較してはるかに低い分離レベルになります。また、このパターンではオンボーディングがシンプルになります。新しいテーブルおよび関連する参照整合性とインデックスの作成が関係してきます。

重要な注意点の 1 つは、Identity and Access Management(IAM)を介した Spanner のアクセス権限は、インスタンス レベルまたはデータベース レベルでのみ提供されることです。テーブルレベルでは、アクセス権を設定できません。また、データベースあたりのテーブル数には 5,000 という上限があります。多くのユーザーは、この制限によってアプリケーションの利用が制限されてしまいます。

さらに、顧客ごとに個別のテーブルを使用すると、スキーマ更新オペレーションのバックログが大きくなる可能性があります。このようなバックログは解決に時間がかかります

HR アプリケーションの場合、SaaS プロバイダは顧客ごとに一連のテーブルを作成します。その際、テーブル名の接頭辞として tenant ID を使用します(例: customer1_employeecustomer1_payrollcustomer1_department)。

次の図に示すように、スキーマのデータ管理パターンには、テナントごとに一連のテーブルが 1 つあります。

スキーマのデータ管理パターンには、テナントごとに一連のテーブルが 1 つあります。

次の表で、スキーマのデータ管理パターンがさまざまな基準にどのように影響するかを示します。

条件 スキーマ - テナントのデータ管理パターンごとに一連のテーブルが 1 つ
分離
  • 低レベルの分離
  • テーブルレベルのセキュリティなし
アジリティ
  • 顧客のオンボーディング作業は簡単
    • 新しいテーブルの作成
    • 関連するキーとインデックスの作成
  • 顧客のオフボーディングはテーブルの削除を意味する
    • データベース内の他のテナントに対し、一時的にパフォーマンスに悪影響がある可能性がある
運用
  • テナントの個別のオペレーションなし
  • バックアップ、モニタリング、ロギングは、個別のアプリケーション関数またはユーティリティ スクリプトとして実装する必要がある
規模
  • 数千のノード
  • 無制限のテナント拡張
  • 1 つのデータベースに含めることができるテーブル数は 5,000 まで
    • 各データベースのテナントのフロア数(5,000 / <テナントのテーブル数>)のみ
    • データベースが 5,000 テーブルを超える場合は、追加テナント用に新しいデータベースを追加
パフォーマンス
  • 高いレベルのリソース競合が可能
  • 一連のテーブルごとにインデックスを別々に設計することで、優れたパフォーマンスを確保
規制要件とコンプライアンス要件
  • ロケーション リージョンが特定のデータ所在地の規制要件を満たす必要がある
  • 特定のセキュリティ制御と監査管理の実装は、同じデータベース内に存在するすべてのテナントに影響を与える

要約すると、重要なポイントは次のとおりです。

  • アドバンテージ: オンボーディングは簡単
  • デメリット: オペレーション上のオーバーヘッドが増加、テーブルレベルのセキュリティ制御がない

スキーマのデータ管理パターンは次のシナリオに適しています。

  • メンテナンスの容易さに比べて、厳格なデータ セキュリティ分離が問題にならないさまざまな部門に対応する内部アプリケーション。
  • 法的要件や規制上の要件に基づいてデータを厳密に分離する必要がないマルチテナント アプリケーション。

データベース内に複数のテーブルセット(各セットが 1 つのテナントに対応)を作成することは可能ですが、データベースの観点からこれは最も望ましくないパターンです。主な理由として、テーブルは命名規則に従う必要があるからです。アプリケーションとデータベース ツール(IDE、スキーマ移行ツールなど)は、命名規則を理解する必要があります。また、テナントに相応してテーブル数が多い場合、スキーマのデータ管理パターンで十分なスケーリングを行うことができません。

より良い方法としては、テナントごとに 1 つのデータベースを割り当ててインスタンス数を増やすか、テーブルデータ管理パターンへの移行をおすすめします。

テーブル

最終的なデータ管理パターンでは、共通のテナントセットを持つ複数のテナントにサービスを提供します。各テーブルには複数テナントのデータが含まれます。データ管理パターンはマルチテナントの究極の姿であり、インフラストラクチャからスキーマ、データモデルまで、すべてが複数のテナント間で共有されます。テーブル内では、主キーに基づいて行が分割され、tenant ID がキーの最初の要素となります。スケーリングの観点から Spanner はこのパターンを最大限にサポートしています。これは、テーブルを無限にスケーリングできるためです。

HR アプリケーションの場合、給与支払テーブルの主キーは customerIDpayrollID の組み合わせになります。

次の図に示すように、テーブルデータ管理パターンには複数のテナント用にテーブルが 1 つあります。

テーブルのデータ管理パターンでは、複数のテナントに 1 つのテーブルを使用します。

スキーマ パターンと同様に、テーブル パターンのデータアクセスをテナント単位で制御することはできません。各テナントが固有のデータベース テーブルを持っている場合、テーブル数を減らすことでスキーマ更新オペレーションを高速化できます。この方法により、オンボーディング、オフボーディング、オペレーションが簡素化されます。

次の表で、テーブルデータ管理パターンがさまざまな基準にどのように影響するかを示します。

条件 テーブル - 複数のテナントのデータ管理パターンを示す 1 つのテーブル
分離
  • 分離レベルが最も低い
  • テナントレベルのセキュリティなし
アジリティ
  • オンボーディング時にデータベース側での設定は不要
    • アプリケーションによる既存のテーブルへのデータの直接書き込みが可能
  • オフボーディングはテーブル内の顧客の行を削除することを意味する
運用
  • バックアップ、モニタリング、ロギングなどのテナントごとの個別のオペレーションはない
  • テナント数の増加に対するオーバーヘッドはほとんど、またはまったくない
規模
  • 数千のノードにスケーリング
  • あらゆるレベルのテナントの増加に対応可能
  • テナントの数を無制限にサポート
パフォーマンス
  • Spanner のコンテキストでは、パターンが適切に機能
  • 内部分散ストレージ、処理、負荷分散は、このパターンで簡単に処理可能
  • 主キースペースを慎重に設計していない場合、高レベルのリソース競合が起こる可能性がある(ノイジー ネイバー)
    • 同時実行と分散の防止が可能
  • ベスト プラクティスに従うことが重要
  • テナントのデータを削除すると、負荷に一時的な影響が出る可能性がある
規制要件とコンプライアンス要件
  • ロケーションが特定のデータ所在地の規制要件を満たす必要がある
  • インスタンスまたはデータベース パターンに比べると、システムレベルのパーティショニングを提供できない
  • 特定のセキュリティおよび監査の管理機能の実装がすべてのテナントに影響を与える

要約すると、重要なポイントは次のとおりです。

  • アドバンテージ: 優れたスケーラビリティ、運用上のオーバーヘッドが少ない
  • デメリット: リソースの競合が多い、各テナントのセキュリティ制御の欠如

このパターンは、次のようなシナリオに最適です。

  • メンテナンスの容易さに比べて、厳格なデータ セキュリティ分離が問題にならないさまざまな部門に対応する内部アプリケーション。
  • リソースのプロビジョニングの最小化を同時に行う場合の、無料枠のアプリケーション機能を使用するテナント向けの最大リソース共有。

データ管理パターンとテナント ライフサイクル管理

次の表は、すべての高いレベルの基準を満たすさまざまなデータ管理パターンの概要を示しています。

インスタンス データベース スキーマ テーブル
分離 完全 完全 最低
アジリティ 中程度 中程度 最高
運用のしやすさ
規模 制限付き 非常に制限される可能性がある
パフォーマンス* 中程度 中程度 高い可能性がある
規制とコンプライアンス 最高

* パフォーマンスはスキーマ設計クエリのベスト プラクティスに大きく依存します。この値は、あくまでも平均的な期待値です。

特定のマルチテナント アプリケーションに対する最適なデータ管理パターンは、基準に基づいてほとんどの要件を満たしているものです。不要な特定の基準がある場合はその行を無視できます。

統合されたデータ管理パターン

多くの場合、マルチテナント アプリケーションの要件を満たすには単一のデータ管理パターンで十分です。それが当てはまる場合、設計で単一のデータ管理パターンを想定できます。

ただし、無料枠、通常の階層、エンタープライズ層をサポートするマルチテナント アプリケーションなど、一部のマルチテナント アプリケーションでは同時に複数のデータ管理パターンが必要になります。

  • 無料枠:

    • 費用対効果を高める必要がある
    • データ量の上限がある
    • 通常は機能が限定される
    • 無料枠での選択肢としてはテーブルデータ管理パターンが適切
      • テナント管理はシンプル
      • 特定のテナント リソースまたは排他的なテナント リソースを作成する必要がない
  • 通常の階層:

    • 費用を支払っている顧客で、スケーリングや分離に対する強い要件が特にない場合に適している
    • 通常の階層での選択肢としては、スキーマデータ管理パターンまたはデータベース データ管理パターンが適切
      • テーブルとインデックスはテナント専用
      • データベースのデータ管理パターンでのバックアップが容易
      • スキーマのデータ管理パターンではバックアップに対するサポートはなし
        • テナント バックアップは、Spanner の外部のユーティリティとして実装する必要がある
  • エンタープライズ階層:

    • 通常、すべての面で完全な自律性を持つ高級階層
    • テナントは、専用のスケーリングや完全分離などの専用リソースを保有
    • インスタンスのデータ管理パターンは、エンタープライズ層に適している

ベスト プラクティスは、データベースごとに異なるデータ管理パターンを維持することです。Spanner データベース内で異なるデータ管理パターンを組み合わせることは可能ですが、その場合、アプリケーションのアクセス ロジックとライフサイクル オペレーションの実装が困難になります。

アプリケーション設計のセクションで、1 つのデータ管理パターンまたは複数のデータ管理パターンを使用する場合の、マルチテナント アプリケーション設計上の考慮事項について概説します。

テナント ライフサイクルを管理する

テナントにはライフサイクルがあります。したがって、マルチテナント アプリケーションに対応する管理オペレーションを実装する必要があります。テナントの作成、更新、削除の基本的なオペレーションに加えて、次のようなデータ関連のオペレーションも検討してください。

  • テナントデータのエクスポート:

    • テナントを削除する場合は、先にデータをエクスポートし、場合によりテナントがデータセットを使用できるようにすることをおすすめします。
    • テーブルまたはスキーマのデータ管理パターンを使用する場合、マルチテナント アプリケーション システムはエクスポートを実装するか、データベース機能(データベースのエクスポート)にマッピングする必要があります。
  • テナントデータのバックアップ:

    • インスタンスまたはデータベースのデータ管理パターンを使用し、個々のテナントのデータのバックアップを行う場合は、データベースのエクスポート関数またはバックアップ関数を使用します。
    • スキーマまたはテーブルのデータ管理パターンを使用して個々のテナントデータをバックアップする場合、マルチテナント アプリケーションはこのオペレーションを実装する必要があります。Spanner データベースは、どのデータがどのテナントに属するものか特定できません。
  • テナントデータの移動:

    • あるデータ管理パターンからテナントを移行する(またはインスタンスまたはデータベース間で同じデータ管理パターン内でテナントを移動する)には、テーブルデータ管理パターンからデータを抽出し、そのデータをデータベース データ管理パターンに挿入する必要があります。

    • ノイジーネイバーの状況の軽減が、テナントを移動するもう 1 つの理由です。

アプリケーション設計

マルチテナント アプリケーションを設計する際は、テナント認識型のビジネス ロジックを実装します。つまり、アプリケーションがビジネス ロジックを実行するのは、常に既知のテナントのコンテキスト内に限られることになります。

データベースの観点からみると、アプリケーションの設計とはテナントが存在するデータ管理パターンに対して各クエリを実行する必要があることを意味しています。以下のセクションでは、マルチテナント アプリケーション設計の中心となるいくつかのコンセプトについて説明します。

テナントの動的接続とクエリ構成

テナントデータからテナント アプリケーションのリクエストへの動的マッピングには、マッピング構成が使用されます。

  • データベース データ管理パターンまたはインスタンス データ管理パターンでは、接続文字列でテナントデータにアクセスできます。
  • スキーマのデータ管理パターンでは、正しいテーブル名を決定する必要があります。
  • テーブルのデータ管理パターンについては、データベースに対してクエリを実行する必要があります。適切な述語を使用して、特定のテナントのデータを取得します。

テナントは、4 つのデータ管理パターンのどれにでも配置できます。次のマッピング実装は、すべてのデータ管理パターンを同時に使用するマルチテナント アプリケーションの一般的な接続構成に対応するものです。あるテナントが 1 つのパターン内に存在する場合、一部のマルチテナント アプリケーションは、すべてのテナントに対して 1 つのデータ管理パターンを使用します。このケースは、次のマッピングで暗黙的にカバーされています。

テナントがビジネス ロジック(従業員がテナント ID を使用してログインする場合など)を実行する場合、アプリケーション ロジックでテナントのデータ管理パターン、特定のテナント ID のデータの場所、およびオプションでテーブルの命名規則(スキーマ パターン用)を決定する必要があります。

このアプリケーション ロジックでは、テナントからデータ管理パターンのマッピングを行う必要があります。次のコードサンプルでは、connection string はテナントデータが存在するデータベースを示しています。このサンプルでは、Spanner インスタンスとデータベースを識別します。データ管理パターンがインスタンスとデータベースの場合、次のコードを使用するだけで、アプリケーションは接続してクエリを実行します。

tenant id -> (data management pattern,
             database connection string,
             [table_prefix])

スキーマとテーブルのデータ管理パターンには追加の設計が必要です。

スキーマのデータ管理パターン

スキーマのデータ管理パターンの場合、同じデータベース内に複数のテナントがあります。各テナントには固有のテーブルがあります。テーブルは名前で区別されます。どのテーブルがどのテナントのものかを明確にします。

1 つの方法としては、テーブル名にテナント ID を付加します。たとえば、EMPLOYEE テーブルは、ID が 356 のテナントに対して T356_EMPLOYEE といいます。アプリケーションは、マッピングが返されたデータベースにクエリを送信するときに、各テーブルの先頭に Ttenant ID という接頭辞を付ける必要があります。

もう 1 つの方法は、クエリで使用するマッピングの先頭に table_prefix を付加し、テナントに適したテーブルを見つけることです。

混合のアプローチもあります。データ管理パターンがスキーマ パターンで、テーブルの接頭辞が空の場合、デフォルトのマッピングが行われます(テーブル名をテナント ID と置き換え)。

テーブルのデータ管理パターン

テーブルのデータ管理パターンにも同様の設計が必要です。このパターンでは、スキーマが 1 つあります。テナントデータは行として保存されます。データへのアクセス権を適切に取得するには、各クエリに述語を追加して、適切なテナントを選択してください。

適切なテナントを見つける方法の 1 つは、各テーブルに TENANT という列を用意することです。列の値は tenant ID です。各クエリは、既存の WHERE 句に述語 AND TENANT = tenant ID を追加するか、述語 AND TENANT = tenant ID を含む WHERE 句を追加する必要があります。

データベースに接続して適切なクエリを作成するには、アプリケーション ロジックでテナント ID を使用できる必要があります。パラメータとして渡すことも、スレッド コンテキストとして保存することもできます。

一部のライフサイクル オペレーションでは、テナントからデータ管理パターンへのマッピング構成を変更する必要があります。たとえば、データ管理パターン間でテナントを移動する場合は、データ管理パターンとデータベース接続文字列を更新する必要があります。テーブル接頭辞の更新が必要になることもあります。

クエリの生成とアトリビューション

マルチテナント アプリケーションの基本的な原則は、複数のテナントが単一のクラウド リソースを共有できることです。前述のデータ管理パターンは、単一のテナントが単一の Spanner インスタンスに割り当てられる場合を除き、このカテゴリに分類されます。

リソースの共有は、データの共有に限りません。モニタリングとロギングも共有されます。たとえば、テーブルのデータ管理パターンとスキーマのデータ管理パターンでは、すべてのテナントに対するすべてのクエリが同じ監査ログに記録されます。

クエリがログに記録されると、クエリテキストを調べて、クエリの対象テナントを判別する必要があります。テーブルのデータ管理パターンでは、プレディケートを解析する必要があります。スキーマのデータ管理パターンでは、テーブル名の 1 つを解析する必要があります。

データベースのデータ管理パターンまたはインスタンス データ管理パターンでは、クエリテキストにはテナント情報はありません。これらのパターンのテナント情報を取得するには、テナントからデータ管理パターンのマッピング テーブルにクエリを実行する必要があります。

クエリテキストを解析せずに特定のクエリのテナントを決定すると、ログとクエリを簡単に分析できるようになります。すべてのデータ管理パターンにわたってクエリのテナントを均一に識別する方法の 1 つとして、クエリテキストに tenant ID と(必要に応じて)label を含むコメントを追加する方法があります。

次のクエリは、TENANT 356 で識別されたテナントのすべての従業員データを選択するものです。SQL 構文の解析とプレディケートからのテナント ID の抽出を回避するため、コメントとしてテナント ID が追加されています。コメントにより、SQL 構文を解析することなく抽出が可能になります。

select * from EMPLOYEE
  -- TENANT 356
  where TENANT = 'T356';

または

select * from T356_EMPLOYEE;
  -- TENANT 356

この設計では、テナントに関して実行するすべてのクエリは、データ管理パターンに関係なくそのテナントに関連付けられます。テナントが 1 つのデータ管理パターンから別のデータ管理パターンに移動された場合、クエリテキストが変更されることがありますが、クエリテキスト内のアトリビューションは同じままです。

上記のコードサンプルはメソッドの 1 つにすぎません。もう 1 つの方法は、ラベルと値の代わりに JSON オブジェクトをコメントとして挿入することです。

select * from T356_EMPLOYEE;
  -- {"TENANT": 356}

テナント アクセス ライフサイクルのオペレーション

設計の考え方に応じて、マルチテナント アプリケーションは、前述のデータ ライフサイクル オペレーションを直接実装することも、別のテナント管理ツールを作成することもできます。

実装戦略に関係なく、ライフサイクル オペレーションはアプリケーション ロジックを実行していないときに実行する必要があります。たとえば、テナントのデータ管理パターンを別のデータ管理パターンに移行している間は、データが単一のデータベースに存在しないため、アプリケーション ロジックは実行できません。データが単一のデータベース内にない場合、アプリケーションの観点から、次の 2 つの操作が必要になります。

  • テナントの停止: アプリケーション ロジックによるすべてのアクセスが無効になります。データ ライフサイクルのオペレーションは可能です。
  • テナントの開始:アプリケーション ロジックによるテナントデータへのアクセスが可能です。アプリケーション ロジックに干渉するライフサイクル オペレーションは無効になります。

頻繁には使用されないものの、テナントの緊急シャットダウンが重要なライフサイクル オペレーションとなることがあります。違反が疑われる場合で、アプリケーション ロジックだけでなくライフサイクル オペレーションも含めたテナントのデータに対するすべてのアクセスの禁止が必要な場合は、このシャットダウンを使用します。違反はデータベースの内部または外部で発生する可能性があります。

緊急状態を削除するライフサイクル オペレーションも必要です。このようなオペレーションでは、相互制御を実装するために、複数の管理者による同時ログインを必須とするように設定することも可能です。

アプリケーションの分離

さまざまなデータ管理パターンによって、テナントデータの分離の度合いが異なります。分離レベル(インスタンス)から最小分離レベル(テーブル)まで、さまざまな分離が可能です。

マルチテナント アプリケーションのコンテキストでは、類似したデプロイメント決定を行う必要があります。つまり、すべてのテナントが同じアプリケーション デプロイメントを使用して、(同じデータ管理パターンで)データにアクセスできるかどうか、が大事です。たとえば、1 つの Kubernetes クラスタがすべてのテナントをサポートしている場合、1 つのテナントがデータにアクセスすると同クラスタがビジネス ロジックを実行します。

または、データ管理のパターンの場合であれば、アプリケーションのデプロイごとに異なるテナントが転送される場合があります。大規模なテナントはそれ専用のアプリケーション デプロイメントにアクセスできますが、小規模または無料枠のテナントはアプリケーション デプロイメントを共有します。

この記事で説明するデータ管理パターンを同等のアプリケーションのデータ管理パターンと完全に一致させるのではなく、すべてのテナントが単一のアプリケーション デプロイメントを共有できるよう、データベースのデータ管理パターンを使用できます。これらのすべてのテナントは、データベースのデータ管理パターンを持ち、1 つのアプリケーション デプロイメントを共有することが可能です。

マルチテナンシーは重要なアプリケーション設計データ管理パターンで、特にリソースの効率性が重要な役割を果たします。Spanner は、さまざまなデータ管理パターンをサポートしています。マルチテナント アプリケーションの実装にご利用ください。Spanner の最高度のスケーラビリティと厳格な SLA により、大規模なマルチテナント アプリケーションのデプロイメントに最適です。

次のステップ

  • Google Cloud に関するリファレンス アーキテクチャ、図、チュートリアル、ベスト プラクティスを確認する。Cloud Architecture Center を確認します。