Multi tenancy
On a SaaSデータ分析プラットフォームでは、組織、顧客、またはビジネスユニットなどの複数のテナントが同じデータベースインフラストラクチャを共有しつつ、それぞれのデータを論理的に分離しておくことが一般的です。これにより、異なるユーザーが同じプラットフォーム内で自分のデータに安全にアクセスすることが可能になります。
要件に応じて、マルチテナンシーを実装するためのさまざまな方法があります。以下は、ClickHouse Cloudを使用してそれらを実装する方法のガイドです。
Shared table
このアプローチでは、すべてのテナントのデータが1つの共有テーブルに格納され、各テナントのデータを識別するためにフィールド(またはフィールドのセット)が使用されます。パフォーマンスを最大化するために、このフィールドは primary key に含めるべきです。ユーザーがそれぞれのテナントに属するデータのみアクセスできるようにするために、role-based access control を使用し、row policiesを介して実装します。
私たちはこのアプローチを推奨します。これは管理が最も簡単であり、特にすべてのテナントが同じデータスキーマを共有し、データ量が中程度(< TBs)である場合に有効です。
すべてのテナントデータを1つのテーブルに集約することで、最適化されたデータ圧縮とメタデータのオーバーヘッドの削減により、ストレージの効率が向上します。加えて、すべてのデータが中央管理されているため、スキーマの更新も簡素化されます。
この手法は、大量のテナント(数百万の可能性があります)を処理するために特に効果的です。
ただし、テナントが異なるデータスキーマを持つ場合や、時間の経過とともに分岐することが予想される場合は、他のアプローチがより適しているかもしれません。
テナント間でデータの量に大きな差がある場合は、小規模なテナントが不必要なクエリパフォーマンスの影響を受ける可能性があります。この問題は、テナントフィールドを主キーに含めることで大幅に軽減されます。
Example
これは共有テーブルのマルチテナンシーモデルの実装例です。
まず、tenant_id
フィールドを主キーに含む共有テーブルを作成します。
次に、偽データを挿入します。
次に、user_1
と user_2
の2つのユーザーを作成します。
私たちは create row policies を作成し、user_1
と user_2
のテナントデータのみにアクセスを制限します。
次に、共通の役割を使用して共有テーブルに対して GRANT SELECT
権限を付与します。
これで、user_1
として接続し、シンプルなセレクトを実行できます。最初のテナントからの行のみが返されます。
Separate tables
このアプローチでは、各テナントのデータが同じデータベース内の別のテーブルに格納され、テナントを識別するための特定のフィールドが不要になります。ユーザーアクセスは GRANT statement を使用して強制され、各ユーザーは自分のテナントデータを含むテーブルにのみアクセスできるようにします。
テナントが異なるデータスキーマを持つ場合、別のテーブルを使用することは良い選択です。
非常に大きなデータセットを持つ少数のテナントが関与するシナリオでは、クエリパフォーマンスが重要な場合、このアプローチは共有テーブルモデルを上回ることがあります。他のテナントのデータをフィルタリングする必要がないため、クエリがより効率的になることができます。さらに、主キーは追加のフィールド(テナントIDなど)を主キーに含める必要がないため、さらに最適化できます。
ただし、このアプローチは1000のテナントにはスケーラブルではありません。 usage limits を参照してください。
Example
これは、別々のテーブルのマルチテナンシーモデルの実装例です。
まず、tenant_1
からのイベント用のテーブルと、tenant_2
からのイベント用のテーブルの2つを作成します。
偽データを挿入します。
次に、user_1
とuser_2
の2つのユーザーを作成します。
次に、それぞれのテーブルに対して GRANT SELECT
権限を付与します。
これで、user_1
として接続し、このユーザーに対応するテーブルからシンプルなセレクトを実行できます。最初のテナントからの行のみが返されます。
Separate databases
各テナントのデータは、同じClickHouseサービス内の別々のデータベースに格納されます。
このアプローチは、各テナントが多数のテーブルと場合によってはマテリアライズドビューを必要とし、異なるデータスキーマを持つ場合に便利です。ただし、テナントの数が多い場合は管理が難しくなることがあります。
実装は、別のテーブルアプローチと似ていますが、権限をテーブルレベルで付与する代わりに、データベースレベルで権限が付与されます。
このアプローチは、1000のテナントにはスケーラブルではありません。 usage limits を参照してください。
Example
これは、別のデータベースのマルチテナンシーモデルの実装例です。
まず、tenant_1
用のデータベースと、tenant_2
用のデータベースの2つを作成します。
偽データを挿入します。
次に、user_1
とuser_2
の2つのユーザーを作成します。
次に、それぞれのテーブルに対して GRANT SELECT
権限を付与します。
これで、user_1
として接続し、適切なデータベースのイベントテーブルでシンプルなセレクトを実行できます。最初のテナントからの行のみが返されます。
Compute-compute separation
上記で説明した3つのアプローチは、Warehousesを使用してさらに分離することができます。データは共通のオブジェクトストレージを介して共有されますが、各テナントは compute-compute separation により異なるCPU/メモリ比率を持つ独自のコンピューティングサービスを持つことができます。
ユーザー管理は、ウェアハウス内のすべてのサービスが share access controls を共有するため、前述のアプローチと似ています。
ウェアハウス内の子サービスの数は限られていますので、Warehouse limitations を参照してください。
Separate Cloud service
最も根本的なアプローチは、テナントごとに異なるClickHouseサービスを使用することです。
この一般的ではない方法は、テナントのデータが法律、セキュリティ、または近接性の理由から異なる地域に保存される必要がある場合に解決策となるでしょう。
各サービスにおいて、ユーザーはそれぞれのテナントのデータにアクセスするためのユーザーアカウントを作成する必要があります。
このアプローチは管理が難しく、各サービスには独自のインフラストラクチャが必要なため、オーバーヘッドが生じます。サービスは、ClickHouse Cloud APIを介して管理することができ、official Terraform providerを使用してオーケストレーションも可能です。
Example
これは、別サービスのマルチテナンシーモデルの実装例です。例では、1つのClickHouseサービスにテーブルとユーザーを作成する方法が示されていますが、これをすべてのサービスに複製する必要があります。
まず、events
テーブルを作成します。
偽データを挿入します。
次に、user_1
を作成します。
次に、対応するテーブルに対して GRANT SELECT
権限を付与します。
これで、テナント1のサービスでuser_1
として接続し、シンプルなセレクトを実行できます。最初のテナントからの行のみが返されます。