Multi-tenant アーキテクチャー 実現方法 (2)
マルチテナント方式の概要
マルチテナント方式とは、単一のソフトウェアインスタンスとそれをサポートするインフラストラクチャを使用して、複数の顧客 (テナント) にサービスを提供するソフトウェアアーキテクチャです。この方式では、各テナントのデータは分離され、他のテナントからアクセスできないようになっています。
- 各テナントは、あたかも自分たち専用のソフトウェアインスタンスを使用しているかのようにサービスを利用できますが、実際にはリソースを共有することでコスト削減や効率的な運用を実現しています。
- マルチテナント方式を採用する主なメリットは、リソースの効率的な利用とコスト削減です。 単一のインフラストラクチャを共有することで、ハードウェア、ソフトウェア、および運用コストを削減できます。また、メンテナンスやアップグレードも一元的に行うことができるため、管理の負担を軽減できます。
- さらに、マルチテナント方式では、テナントごとに個別のシステムを構築・運用する必要がないため、迅速なサービス提供が可能になります。 マルチテナントアプリケーションでは、「組織」はユーザーやリソースをグループ化する方法として有効です。
- 組織は、異なるクライアントやグループがアプリケーションを使用する際に、それぞれに独自のユーザー、データ、および設定を持つ別々のセクションのように機能します。これにより、特定のサービスと管理を提供しやすくなります。 ただし、マルチテナント方式では、テナント間のデータ分離、パフォーマンスの安定性、リソース管理など、いくつかの課題も存在します。
- これらの課題に対処するためには、適切なアーキテクチャ設計、セキュリティ対策、および運用管理が必要となります。
Aurora (RDB) を管理するベストプラクティス
Amazon Aurora は、MySQL および PostgreSQL と互換性のある、クラウドネイティブなリレーショナルデータベースです。メタデータを Aurora で管理する場合、以下を考慮する必要があります。
テナント分離
Aurora では、以下の方法でテナント分離を実現できます。
- サイロモデル: 各テナントに専用のデータベースインスタンスを提供します。この方法では、テナント間の分離が最も高くなりますが、コストが高くなる可能性があります。
- ブリッジモデル: 同じデータベースインスタンスを共有しますが、テナントごとに異なるスキーマを使用します。このモデルは、リソースの共有によりコストを削減できますが、スキーマの管理が複雑になる可能性があります。
- プールモデル: 同じデータベースインスタンスと名前空間を共有し、各テーブルにテナント識別子を使用してデータを分離します。このモデルは、運用コストを最も削減できますが、データアクセス制御の実装が複雑になる可能性があります。
どのモデルを選択するかは、テナントの規模、セキュリティ要件、およびコストなどを考慮して決定する必要があります。例えば、セキュリティ要件が厳格な場合はサイロモデルが適していますが、コストを重視する場合はプールモデルが適している可能性があります。
スキーマ設計
マルチテナント環境では、スキーマ設計も重要な要素です。以下の点を考慮する必要があります。
- テナント識別子: 各テーブルにテナント識別子を含めることで、テナントのデータを区別します。
- 共通テーブル: すべてのテナントで共有するデータは、共通テーブルに格納します。
- テナント固有テーブル: テナント固有のデータは、テナント固有のテーブルに格納します。
- スキーマのバージョン管理: スキーマの変更は、互換性を維持しながら行う必要があります。
- グローバル一意識別子 (GUID): 共有データベースモデルを使用する場合は、すべてのテーブルの主キーに GUID を使用します。これにより、データベース間でテナントを移行したり、データセットをマージしたりする際に、キーの衝突を防ぐことができます。
アプリケーション設計
アプリケーションを設計する際には、テナントを意識した設計が重要です。
- リクエストにテナント情報を自動的に挿入するミドルウェアまたはサービス層を使用します。
- アプリケーションスタック全体で、どのテナントがリクエストを行っているかについてのコンテキストを維持します。
カスタマイズ
テナントに一定のカスタマイズを許可することで、ユーザー満足度を高めることができます。
- 設定可能な機能: テナントが他のテナントに影響を与えることなく、アプリケーション内の機能や設定をカスタマイズできるようにします。
- API アクセス: テナントがシステムを統合したり、必要に応じて機能を拡張したりできる API を提供します。
- 機能フラグ: 特定のテナントの機能を有効または無効にするために、機能フラグを実装します。これにより、新機能を段階的に展開したり、テナント固有の機能を管理したりするのに役立ちます。
リソース割り当て
マルチテナント環境では、リソースの効率的な利用が重要です。
- 動的リソース割り当て: テナント間で共有リソースの使用を最適化し、パフォーマンスを向上させます。これには、テナントからのリアルタイムの需要に基づいて、コンピューティング能力やストレージなどのリソースを自動的にスケーリングすることが含まれます。
- リソースクォータ: 1つのテナントがリソースを独占しないように、テナントごとにリソースクォータを実装します。
アクセス制御
Aurora では、IAM データベース認証、Amazon RDS Proxy、Kerberos 認証など、さまざまなアクセス制御メカニズムを使用できます。これらのメカニズムを適切に設定することで、テナントのデータへの不正アクセスを防ぐことができます。
- Workload Identity Federation: Google Cloud サービスへのアクセスを許可するために、Workload Identity Federation for GKE を使用します。これにより、アクセス管理を簡素化し、セキュリティを向上させることができます。
- 最小権限の原則: 特定のタスクを実行するために必要な最小限のアクションのみを実行できるように、ID に権限を付与する必要があります。これにより、意図しないアクセスを制限し、どのリソースに誰がアクセスできるかを追跡するのに役立ちます。
- ロールベースのアクセス制御 (RBAC) と属性ベースのアクセス制御 (ABAC): ユーザーのロールと属性に基づいてアクセスを制限するために、RBAC と ABAC を利用します。これにより、きめ細かいアクセス制御を実現し、データへの不正アクセスを防ぐことができます。
パフォーマンス最適化
Aurora のパフォーマンスを最適化するには、以下の方法を検討できます。
- ストレージの自動スケーリング: ストレージ容量を自動的に調整することで、パフォーマンスを維持します。
- インスタンスのスケーリング: 読み取りレプリカを追加することで、読み取り負荷を分散します。
- 接続管理: アイドル状態の接続を適切に管理することで、リソースの消費を抑えます。
- クエリの実行計画の管理: クエリのパフォーマンスを分析し、最適化します。
- Aurora I/O-Optimized: 読み取り/書き込み I/O 操作の料金を削減し、スループットを向上させます。
- ベースラインパフォーマンスの確立: まず、ワークロードのベースラインとなるパフォーマンスを確立します。さまざまな間隔でパフォーマンスメトリクスを記録し、変化を監視することで、パフォーマンスの問題を早期に発見することができます。
- アクティビティの急増への対応: データベースクエリを改善し、リソースの自動スケーリングを導入することで、ピーク時のパフォーマンスを向上させます。
OpenSearchを管理するベストプラクティス
Amazon OpenSearch Service は、OpenSearch のマネージドサービスです。検索インデックスを OpenSearch で管理する場合、以下を考慮する必要があります。
インデックス設計
マルチテナント環境では、インデックス設計も重要な要素です。以下の点を考慮する必要があります。
- テナント分離: 各テナントに専用のインデックスを作成するか、共通のインデックスにテナント識別子を含めることで、テナントのデータを区別します。
- インデックスのサイズ: 各シャードのサイズを 30~50 GiB 程度に維持すること で、パフォーマンスを最適化します。
- マッピング: 各フィールドに適切なマッピングを定義することで、検索の精度を向上させます。
- データ量の見直し: 検索に使用する項目と使用しない項目を洗い出し、不要なインデックス作成を避けることで、パフォーマンスを向上させ、ストレージコストを削減できます。
- シャード数の管理: シャード数が多すぎると、OpenSearch のパフォーマンスが低下する可能性があります。Java ヒープ 1 GiB あたりのシャード数を 25以下に維持すること が推奨されます。
- エイリアス: エイリアスは、1つ以上の物理インデックスを参照する仮想インデックスであり、データ管理と検索を簡素化します。OpenSearch では、エイリアスにアクセス制御ルールを定義して、データアクセスに対する適切なセキュリティと制御を確保できます。
- 多言語検索: 多言語検索のユースケースでは、言語ごとに異なるインデックスタイプを使用することを検討します。例えば、英語、フランス語、ドイツ語の検索を行う場合は、それぞれに専用のインデックスを作成することで、分析と関連性の精度を向上させることができます。
- プールモデル: プールモデルを使用する場合は、言語ごとにフィールドを使用することで、ターゲットを絞った言語分析が可能になり、言語間の関連性の影響を軽減できます。
テナント分離
OpenSearch では、以下の方法でテナント分離を実現できます。
- ドメインごとのサイロモデル: 各テナントに専用のドメインを提供します。この方法では、テナント間の分離が最も高くなりますが、コストが高くなる可能性があります。
- インデックスごとのサイロモデル: 同じドメインを共有しますが、テナントごとに異なるインデックスを使用します。このモデルは、リソースの共有によりコストを削減できますが、インデックスの管理が複雑になる可能性があります。
- プールモデル: 同じドメインとインデックスを共有し、ドキュメントレベルのセキュリティを使用してデータを分離します。このモデルは、運用コストを最も削減できますが、アクセス制御の実装が複雑になる可能性があります。
どのモデルを選択するかは、テナントの規模、セキュリティ要件、およびコストなどを考慮して決定する必要があります。また、テナントのデータサイズや使用パターンも考慮する必要があります。小規模なテナントが多い場合は、テナントごとに専用のインデックスを作成すると、リソースが過剰に割り当てられる可能性があります。
アクセス制御
OpenSearch では、Fine-Grained Access Control (FGAC) を使用して、インデックス、ドキュメント、およびフィールドレベルでアクセス制御を行うことができます。FGAC を使用することで、テナントのデータへの不正アクセスを防ぐことができます。
- OpenSearch Security Dashboard: OpenSearch Security Dashboard を使用すると、テナント、ロール、および権限を管理できます。23 これにより、アクセス制御をGUIで簡単に設定できます。
- インデックスレベルのアクセス制御リスト (ACL): ACL を使用すると、インデックスへのアクセスを制御できます。ACL は、glob スタイルのマッチングを使用して、どのインデックスに権限を適用するかを指定します。
- 権限の種類: OpenSearch では、deny、admin、readwrite、read、write などの権限が使用できます。各権限は、インデックスに対するアクセスレベルを決定します。
- トップレベル API へのアクセス: OpenSearch Security management を有効にすると、_mget、_msearch、_bulk などのトップレベル API を制御できます。これにより、API へのアクセスを制限し、セキュリティを向上させることができます。
- IAM リクエスト署名: IAM リクエスト署名を使用して、インデックスレベルのアクセス制御を提供できます。これにより、各テナントにインデックスアクセス許可を提供できます。
- ドキュメントアクセス許可: ドキュメントアクセス許可を使用して、テナントまたはユーザーロールに基づいて特定のドキュメントへのアクセスを制限できます。
パフォーマンス最適化
OpenSearch のパフォーマンスを最適化するには、以下の方法を検討できます。
- リフレッシュ間隔の調整: リフレッシュ間隔を長くすることで、インデックス作成のパフォーマンスを向上させます。
- レプリカ数の調整: レプリカ数を減らすことで、インデックス作成のパフォーマンスを向上させます。
- 一括リクエストサイズの調整: 最適な一括リクエストサイズを使用することで、インデックス作成のパフォーマンスを向上させます。
- レスポンスサイズの縮小: filter_path パラメータを使用して、レスポンスサイズを縮小します。
- フラッシュしきい値サイズの増加: index.translog.flush_threshold_size を増やすことで、フラッシュ操作の頻度を減らします。
- シャードの均等な分散: シャードをデータノード間で均等に分散することで、パフォーマンスを向上させます。
- 非同期検索: リソースを大量に消費するクエリを非同期で実行します。
- 同時セグメント検索: セグメントを同時に検索します。
- スターツリーインデックス: 集計のパフォーマンスを向上させます。
- キャッシング: キャッシングメカニズムを使用して、データベースの負荷を軽減します。
- インデックス作成の最適化: インデックス作成プロセスを最適化します。特に、大量のベクトルを一度にインデックスする場合は、リフレッシュ間隔を無効にする、レプリカを無効にする、インデックス作成スレッドの数を増やす、ベクトルフィールドのストレージを無効にするなどの方法を検討します。
- クエリ最適化: クエリを最適化することで、検索パフォーマンスを向上させることができます。不要なドキュメント結果を収集するようなクエリは、検索速度を低下させるため、避けるべきです。
- スローログ: スローログを使用して、パフォーマンスのボトルネックを特定します。スローログは、遅いクエリを特定し、最適化するのに役立ちます。
- 外部データクエリの高速化: 外部データソースのクエリパフォーマンスを向上させるには、スキップインデックス、カバリングインデックス、およびマテリアライズドビューを使用します。これらのインデックスタイプは、外部データソースを操作する際のクエリパフォーマンスを向上させることができます。
- ホットスポットの監視: ホットスポットは、パフォーマンスに影響を与える可能性があるため、監視する必要があります。ホットスポットを特定し、対処することで、パフォーマンスを向上させることができます。
- アクティブシャードあたりの vCPU: アクティブシャードあたり 1.5 vCPU を使用することを推奨します。これにより、容量計画とリソース割り当てに役立ちます。
- CPU 使用率の監視: インデックス作成スレッドの数を調整する場合は、CPU 使用率を監視する必要があります。CPU 使用率を監視することで、最適なインデックス作成スレッド数を決定できます。
インデックス管理
- Index State Management (ISM): ISM を使用すると、インデックスのライフサイクルを定義し、古いインデックスの削除やアーカイブなどのアクションを自動化できます。
- ロールオーバーアクション: ロールオーバーアクションを使用して、新しいインデックスを自動的に作成し、古いインデックスのライフサイクルを管理できます。
文書管理+検索サービスにおける具体的な適用例
文書管理+検索サービスは、企業内のドキュメントを一元的に管理し、必要なドキュメントを迅速に検索できるサービスです。このサービスをマルチテナント方式で提供する場合、上記のベストプラクティスを適用することで、各テナントのデータを安全かつ効率的に管理できます。 例えば、以下のようなユースケースが考えられます。
- 不動産管理会社: 複数の顧客 (不動産オーナー) の物件情報を管理し、各オーナーに専用の検索インターフェースを提供します。オーナーごとに異なるアクセス権限を設定することで、データの機密性を確保できます。
- 法律事務所: 複数の顧客 (クライアント) の案件情報を管理し、各クライアントにアクセス権限を設定します。案件情報へのアクセスを制限することで、クライアントの機密情報を保護できます。
- 金融機関: 複数の顧客 (顧客企業) の財務情報を管理し、各顧客に専用のレポートダッシュボードを提供します。各顧客にカスタマイズされたダッシュボードを提供することで、顧客満足度を高めることができます。
- 教育機関: 学生、教職員、管理部門など、さまざまなユーザーグループに異なるアクセス権限を持つ文書管理システムを提供します。学生は自分の成績証明書にのみアクセスでき、教職員は担当科目の資料にアクセスでき、管理部門はすべてのドキュメントにアクセスできるように設定できます。
- 製造業: 製品設計図、マニュアル、品質管理記録など、さまざまな種類のドキュメントを管理し、各部門に適切なアクセス権限を設定します。設計部門は設計図にアクセスでき、製造部門はマニュアルにアクセスでき、品質管理部門は品質管理記録にアクセスできるように設定できます。
これらのユースケースでは、Aurora でメタデータを管理し、OpenSearch でドキュメントの全文検索インデックスを管理することで、効率的な文書管理+検索サービスを実現できます。
運用面におけるベストプラクティス
マルチテナント環境では、運用面でも以下のベストプラクティスを考慮する必要があります。
テナントのオンボーディング/オフボーディング
テナントのオンボーディング/オフボーディングプロセスを自動化することで、効率的にテナントを管理できます。オンボーディングプロセスでは、テナントのデータベース、インデックス、およびアクセス権限などを自動的に作成します。オフボーディングプロセスでは、テナントのデータを削除またはアーカイブし、リソースを解放します。
- スムーズなオンボーディングプロセス: 新しいテナントがアプリケーションを迅速にセットアップして使用できるように、スムーズなオンボーディングプロセスを確保することが重要です。これには、テナント登録、初期構成、および必要に応じたデータ移行などのセットアッププロセスの自動化が含まれます。
- 招待フロー: 標準の SaaS オンボーディングプロセスを向上させるために、招待フローを使用します。これにより、コンバージョン率を向上させ、製品の成長を促進することができます。
- データ移行の計画: アプリケーションを設計する際には、将来の移行を考慮に入れておく必要があります。必要に応じて、テナントデータを共有リソースと専用リソース間で簡単に移行できるように、スクリプトまたはツールを作成します。
- Lambda 関数の使用: Lambda 関数を使用して、ユーザーの確認や移行などのユーザー管理タスクを自動化します。
- 構造化されたオフボーディングプロセス: テナントが退去する際の移行を効率的に管理することも重要です。明確な期待を設定し、定義されたチェックリストに従うことで、両当事者が義務を理解し、あいまいさや誤解による紛争のリスクを最小限に抑えることができます。
- チェックリスト: チェックリストを使用することで、オフボーディングプロセスを合理化し、すべての必要な手順が実行されるようにすることができます。チェックリストには、テナントへの連絡、鍵の返却、セキュリティデポジットの返金、公共料金の解約など、オフボーディングに必要なすべてのタスクを含める必要があります。
- 条件付きロジック: さまざまなオフボーディングシナリオに適応するために、チェックリストに条件付きロジックを使用します。これにより、エラーや見落としを減らし、オフボーディングプロセスの効率と精度を向上させることができます。
- 相対期日: 期限を追跡し、オフボーディングタスクの適時完了を確保するために、チェックリストに相対期日を設定します。
- データ収集: テナントからのフィードバックを収集し、物件の状態を文書化するために、チェックリストにデータ収集機能を使用します。
- ロールベースの割り当て: 責任を明確化し、説明責任を維持するために、チェックリストにロールベースの割り当てを使用します。
- マルチメディアサポート: 詳細な検査ドキュメントのために、チェックリストにリンク、ビデオ、画像を埋め込むことで、ドキュメントを強化します。
- ワークフローの自動化: 繰り返しタスクを自動化し、リマインダーを設定するために、チェックリストにワークフローの自動化を使用します。
- API と Webhook または Zapier: チェックリストを他のアプリケーションやサービスと統合するために、API と Webhook または Zapier を使用します。
- リマインダーと通知: 関係者に情報を提供し、進捗状況を把握するために、チェックリストにリマインダーと通知を使用します。
データのバックアップとリストア
定期的なデータのバックアップとリストアは、データ損失を防ぐために不可欠です。Aurora では、自動バックアップとデータベーススナップショットを使用して、データをバックアップできます。OpenSearch では、スナップショットを使用して、インデックスをバックアップできます。
- バックアップの種類: データベースのバックアップには、フルバックアップ、増分バックアップ、差分バックアップなど、さまざまな種類があります。各バックアップタイプには、利点と欠点があります。
- ポイントインタイムリカバリ (PITR): PITR を使用すると、データベースを特定の時点にリストアできます。
- ストリーミングレプリケーション: ストリーミングレプリケーションを使用して、データベースのレプリカを作成できます。
- リストアとリカバリ: バックアップのリストアとは、バックアップと同じ状態に戻すことを指します。リカバリとは、リストアしたデータ、または破損したデータに対して何らかの処理をして最新の状態、または正常な状態に復旧させることを指します。
- ログファイルのバックアップ: データファイルに加えて、データベースログファイルをバックアップすることが重要です。ログファイルは、データベースを一貫した状態にリカバリするために必要です。
- データ損失の可能性: バックアップを取得していても、データが失われる可能性があります。複数のバックアップを作成し、障害が発生した場合に備えて、専門のデータリカバリサービスを検討することが重要です。
- バックアップとリストアに必要な時間: バックアップとリストアの操作には、データ量によってはかなりの時間がかかる場合があります。
- バックアップの暗号化: 機密データを保護するために、バックアップを暗号化することが重要です。暗号化を使用すると、バックアップを保護し、不正アクセスを防ぐことができます。
- Windows のリカバリオプション: Windows では、システムの復元、回復ドライブ、Windows の再インストールなど、さまざまなリカバリオプションを使用できます。
セキュリティ対策
セキュリティ対策は、マルチテナント環境において最も重要な要素です。以下の対策を検討する必要があります。
- アクセス制御: IAM、VPC セキュリティグループ、および FGAC を使用して、テナントのデータへのアクセスを制限します。
- 暗号化: 保存データと転送データを暗号化することで、データの機密性を保護します。
- セキュリティ監査: 定期的なセキュリティ監査を実施し、脆弱性を特定します。
- 脅威の監視: 不審なアクティビティを監視し、迅速に対応します。
- データマスキングとリダクション: 共有環境で機密データを保護するために、データマスキングとリダクションを使用します。データマスキングは、承認されていないユーザーが解読できないようにデータを変換しますが、運用ニーズには使用可能なままにします。リダクションは、ユーザーの権限または規制ガイドラインに基づいて、機密データを部分的または完全に削除します。
- データ主権: データは、それが保存されている国の規制の対象となります。マルチテナントクラウドプロバイダーは、データの所在地と国境を越えたデータフローに関する国内法を尊重する必要があります。
- データベース監査ログ: すべての RDS と Aurora インスタンスでデータベース監査ログを有効にし、関連するすべてのデータを取得するように設定します。Amazon CloudWatch Logs や Amazon Kinesis Data Streams などの集中型ログ管理ソリューションを使用して、データベース監査ログを収集および分析します。データベース監査ログを定期的に監視して不審な活動がないか確認し、問題があれば迅速に調査して解決するための対策を講じます。
- Kubernetes 環境:
- ネットワークポリシーを使用して Pod 通信を制御します。
- GKE Sandbox を使用してワークロードを実行します。
- ポリシーベースのアドミッションコントロールを設定します。
- コントロールプレーンへのネットワークアクセスを制限します。
- テナントの行動の監視: テナントの行動を監視して評価し、不規則性や潜在的な脅威がないか確認します。リアルタイムの異常検知システムを導入し、頻繁にセキュリティ評価を実施することが含まれる場合があります。
- 災害復旧とバックアップメカニズム: アーキテクチャに堅牢な災害復旧およびバックアップメカニズムを組み込みます。これには、定期的なデータバックアップ、冗長システム、および予期しないイベントが発生した場合に事業継続性を確保するための明確に定義された災害復旧計画が含まれる場合があります。
- 強力な暗号化アルゴリズム: 保存データと転送データを保護するために、強力な暗号化アルゴリズムを実装します。
- データベース管理システム、オペレーティングシステム、およびアプリケーションの定期的な更新とパッチ適用: 脆弱性を防ぐために、データベース管理システム、オペレーティングシステム、およびアプリケーションを定期的に更新およびパッチ適用します。
- データベースアクティビティの監視と分析: セキュリティ侵害や異常を検出するために、データベースアクティビティを継続的に監視および分析します。
- データレジデンシー法: GDPR などのデータレジデンシー法を考慮します。これらの法律では、地域ごとにデータを分割する必要がある場合があります。
結論
- マルチテナント方式でデータを管理する場合、テナント分離、スキーマ設計、アクセス制御、パフォーマンス最適化、およびセキュリティ対策など、さまざまな要素を考慮する必要があります。
- さらに、アプリケーションとテナントベースが進化するにつれて、選択したアーキテクチャを定期的に見直すことが重要です。アーキテクチャが現在のニーズを満たしているかどうかを評価し、必要に応じて調整することができます。