マルチテナント ソリューションにおけるメッセージングのアーキテクチャ アプローチ
非同期メッセージングとイベントドリブン通信は、いくつかの内部および外部サービスから構成される分散アプリケーションを構築する際に重要なアセットです。 マルチテナント ソリューションを設計する際は、さまざまなテナントに関連するメッセージを共有またはパーティション分割する方法を定義するために、事前の分析を実施することが重要です。
同じメッセージング システムまたはイベント ストリーミング サービスを共有することで、運用のコストと管理の複雑性を大幅に低減できます。 ただし、各テナントに専用のメッセージング システムを使用すると、データの分離が向上し、データ漏洩のリスクが軽減され、 Noisy Neighbor 問題が解消され、Azure のコストをテナントに簡単に請求できるようになります。
この記事では、メッセージとイベントの違いを説明します。また、ソリューション アーキテクトがマルチテナント ソリューションでメッセージングまたはイベント インフラストラクチャに使用するアプローチを決定する際に参照できるガイドラインを紹介します。
メッセージ、データ ポイント、個別イベント
すべてのメッセージング システムには、同様の機能、トランスポート プロトコル、使用シナリオがあります。 たとえば、ほとんどの最新メッセージング システムでは、揮発性または永続のキューを使用する非同期通信、AMQP および HTTPS トランスポート プロトコル、少なくとも 1 回の配信などがサポートされています。 しかし、パブリッシュされる情報のタイプや、クライアント アプリケーションによってデータが消費および処理される方法をより細かく見てみると、さまざまな種類のメッセージとイベントを区別することができます。 イベントを配信するサービスとメッセージを送信するシステムには、根本的な違いがあります。 詳細については、次のリソースを参照してください。
- Azure メッセージング サービスの中から選択する - Azure Event Grid、Event Hubs、および Service Bus
- イベント、データ ポイント、メッセージ - データに適した Azure メッセージング サービスの選択
イベント
イベントは、状態または状態変更の軽量の通知です。 イベントは、個別の単位またはシリーズの一部になることができます。 イベントは、通知する以外はパブリッシャーの意図を通常伝えないメッセージです。 イベントはファクトをキャプチャして、それを他のサービスまたはコンポーネントに伝達します。 イベントのコンシューマーは、イベントが有益なときにそれを処理でき、パブリッシャーによって抱かれる特定の期待を満たすことはありません。 イベントは主に 2 つのカテゴリに分類できます。
- 個別イベントは、パブリッシュ元のアプリケーションによって実行された特定のアクションについての情報を保持します。非同期のイベントドリブン通信を使用している場合、アプリケーションはそのドメイン内で何かが発生したときに通知イベントをパブリッシュします。 1 つまたは複数のコンシューマー アプリケーションが、製品カタログ アプリケーションにおける価格の変化のように、この状態の変化を認識する必要があります。 コンシューマーはイベントをサブスクライブして、それらを非同期に受け取ります。 特定のイベントが発生すると、コンシューマー アプリケーションはドメイン エンティティを更新する場合があります。これにより、さらに統合イベントをパブリッシュさせることができます。
- シリーズ イベントは、進行中の継続的なストリームの要素として情報提供用のデータ ポイントを保持します (分析用にデバイスから届いた温度測定値やクリック分析アプリケーションにおけるユーザー アクションなど)。 イベント ストリームは特定のコンテキストに関連します (フィールドのデバイスからレポートされる温度や湿度など)。 同じコンテキストに関するすべてのイベントには、厳密な時間的順序があり、それらのイベントをイベント ストリーム処理エンジンによって処理するときに問題になります。 データ ポイントを保持するイベントのストリームを分析するには、目的の時間枠にわたるバッファーに、それらのイベントを累積する必要があります。 または、項目の数を選択したうえで、ほぼリアルタイムのソリューションまたは機械学習アルゴリズムを使用してそれらのイベントを処理できます。 一連のイベントの分析によってシグナルを生成できます (ある時間枠にわたって測定された、しきい値を超える値の平均など)。 これらのシグナルは、その後、アクション可能な個別のイベントとして挙げることができます。
個別イベントは状態の変化をレポートします。また、アクション可能です。 イベント ペイロードには、発生した出来事についての情報が含まれています。ただし、イベントをトリガーした完全なデータはたいてい含まれていません。 たとえば、レポート アプリケーションがストレージ アカウントに新しいファイルを作成したことが、イベントによってコンシューマーに通知されます。 イベント ペイロードには、ファイルについての一般的な情報が含まれていることがありますが、ファイル自体は含まれていません。 個別のイベントは、スケーリングする必要があるサーバーレス ソリューションに最適です。
一連のイベントは、状態を報告し、分析可能です。 個別イベントは、時間順に並べられ、相互に関連付けられています。 コンテキストによっては、コンシューマーは、イベントの完全なシーケンスを受け取って、発生した出来事を分析し、必要なアクションを起こす必要があります。
メッセージ
メッセージには、別の場所で消費または保存するためにサービスによって生成された生データが含まれています。 メッセージは多くの場合、受信側のサービスがワークフローまたは処理チェーン内のステップを実行するために必要な情報を運びます。 このような通信の例としては、コマンド パターンがあります。 また、メッセージの受信者が一連のアクションを実行して処理の結果についてのレポートを非同期メッセージによって返すことを、パブリッシャーが期待する場合もあります。 メッセージのパブリッシャーとメッセージの受信者の間には、取り決めがあります。 たとえば、パブリッシャーはなんらかの生データが含まれたメッセージを送信し、そのデータからコンシューマーがファイルを作成して完了時に応答メッセージを送り返すことを期待します。 別の状況では、送信者プロセスで一方向の非同期メッセージを送信して、別のサービスに特定の操作の実行を依頼するものの、そこから受信確認や応答メッセージが返されることを期待しない場合があります。
この種の取り決めに基づくメッセージ処理は、オーディエンスであるコンシューマー エージェントに個別イベントをパブリッシュするだけで、それらの通知がどのように処理されるかについては特に期待しないパブリッシャーと大きく異なります。
シナリオの例
次のリストでは、メッセージ、データ ポイント、個別イベントについて、マルチテナント シナリオの例をいくつか示しています。
- 個別イベント:
- 音楽共有プラットフォームで、特定のテナント内の特定のユーザーが特定の音楽トラックを聴いたというファクトを追跡する。
- オンライン ストアの Web アプリケーションで、パブリッシャーとサブスクライバーのパターンを使用し、カタログ アプリケーションがイベントを他のアプリケーションに送信してそれらに品目の価格の変更を通知する。
- 製造会社が、設備のメンテナンス、システムの正常性、契約の更新についてのリアルタイム情報を顧客とサード パーティにプッシュする。
- データ ポイント:
- ビルの制御システムが、複数の顧客に属するセンサーからの温度または湿度測定値など、テレメトリ イベントを受信する。
- イベントドリブン監視システムが、複数のサービス (Web サーバーなど) からリアルタイムな形で診断ログを受信して処理する。
- Web ページのクライアント側スクリプトでユーザー アクションを収集し、クリック分析ソリューションに送信する。
- メッセージ:
- B2B の財務アプリケーションでメッセージを受信して、テナントの銀行取引記録の処理を開始する。
- 実行時間の長いワークフローで、次のステップの実行をトリガーするメッセージを受信する。
- オンライン ストア アプリケーションの買い物かごアプリケーションで、非同期の永続メッセージを使用して CreateOrder コマンドを発注アプリケーションに送信する。
主な考慮事項と要件
お客様が自分のソリューションに選択するデプロイおよびテナント モデルは、セキュリティ、パフォーマンス、データの分離、管理、リソースのコストをテナントにクロスチャージする能力に大きく影響します。 この分析には、お客様が自分のメッセージングおよびイベント インフラストラクチャに選択するモデルが含まれます。 このセクションでは、マルチテナント ソリューションでメッセージング システムについて計画する際に行わなければならない重要な決定のうち、いくつかを確認します。
スケール
メッセージングまたはイベント インフラストラクチャについて計画するときには、テナントの数、メッセージ フローとイベント ストリームの複雑さ、メッセージのボリューム、期待されるトラフィック プロファイル、分離レベルを決定に役立てることをおすすめします。
最初のステップは、通常またはピークのトラフィックにおいて予想されるメッセージ ボリュームを適切に処理できるスループットという観点で、徹底的なキャパシティ プランニングを実施して、メッセージング システムに必要な最大キャパシティを確立することです。
Azure Service Bus Premium レベルなど、一部の提供サービスでは、お客様が各ワークロードを分離して実行できるように CPU とメモリのレベルでのリソース分離を提供しています。 このリソースのコンテナーを、メッセージング ユニットと呼びます。 各 Premium 名前空間には、1 つ以上のメッセージング ユニットが割り当てられます。 各 Service Bus Premium 名前空間に対して 1、2、4、8、または 16 のメッセージング ユニットを購入することができます。 1 つのワークロードまたはエンティティが複数のメッセージング ユニットにまたがることができ、必要に応じてメッセージング ユニットの数を変更できます。 その結果、Service Bus ベースのソリューションのパフォーマンスは、予測可能で反復可能になります。 詳細については、「Service Bus の Premium および Standard メッセージング レベル」を参照してください。 同様に、Azure Event Hubs の価格レベルでは、受信および送信イベントの予想ボリュームに基づいて名前空間をサイズ設定できます。 たとえば、Premium オファリングは、基になるインフラストラクチャ内の分離されたリソース (CPU、メモリ、ストレージ) の共有に対応する処理ユニット (PU) によって請求されます。 PU ごとの有効な取り込みとストリームのスループットは、次の要因によって異なります。
- プロデューサーとコンシューマーの数
- ペイロードのサイズ
- [パーティション数]
- エグレス要求率
- Event Hubs Capture、スキーマ レジストリ、その他の高度な機能の使用
詳細については、「Event Hubs Premium の概要」を参照してください。
お客様のソリューションで多数のテナントを扱っていて、テナントごとに別個のメッセージング システムを採用することを決めた場合には、一貫した戦略を用意し、各インフラストラクチャについてそれぞれ別個にデプロイ、監視、アラート、スケーリングを自動化する必要があります。
たとえば、ある特定のテナントのメッセージング システムは、コードとしてのインフラストラクチャ (IaC) ツール (Terraform、Bicep、Azure Resource Manager (ARM) JSON テンプレートなど) と DevOps システム (Azure DevOps や GitHub Actions など) を使用して、プロビジョニング プロセス時にデプロイできます。 詳細については、「マルチテナント ソリューションのデプロイと構成のアーキテクチャに関するアプローチ」を参照してください。
メッセージング システムは、時間単位あたりのメッセージ数の最大スループットによってサイズ設定できます。 システムによって動的な自動スケーリングがサポートされている場合、そのキャパシティは、想定されるサービス レベル アグリーメントを満たすように、トラフィックの状態とメトリックに基づいて自動的に増減できます。
パフォーマンスの予測可能性と信頼性
テナントの数が限られている場合にメッセージング システムを設計して構築するときは、単一のメッセージング システムを使用することが、スループットの点で機能的な要件を満たす優れたソリューションになる可能性があります。また、そうすることで、総保有コストを減らせます。 マルチテナント アプリケーションでは、複数の顧客全体で同じメッセージング エンティティ (キューやトピックなど) を共有する場合があります。 または、テナントの分離性を高めるために、それぞれ専用のコンポーネント セットを使用する場合があります。 一方で、複数のテナント全体で同じメッセージング インフラストラクチャを共有すると、ソリューション全体でうるさい隣人の問題が発生する可能性があります。 1 つのテナントのアクティビティが、パフォーマンスと運用性の点で他のテナントに悪い影響を及ぼすおそれがあります。
この場合、ピーク時に予想されるトラフィックの負荷に耐えられるように、メッセージング システムのサイズを適切にする必要があります。 理想は、自動スケーリングをサポートすることです。 メッセージング システムは動的に、トラフィックが増加したときにはスケールアウトし、トラフィックが減少したときにはスケールインする必要があります。 テナントごとに専用のメッセージング システムを用意することで、うるさい隣人のリスクも軽減できます。しかし、大量のメッセージング システムを管理しようとすると、ソリューションの複雑さが高まるおそれがあります。
マルチテナント アプリケーションでは、最終的にハイブリッド アプローチを採用できます。この場合、内部での非同期通信を実装するために、コア サービスが 1 つの共有メッセージング システムで同じセットのキューとトピックを利用します。 これに対して他のサービスでは、メッセージング エンティティの専用グループ、さらには専用メッセージング システムを採用することで、各テナントでうるさい隣人の問題を抑制し、データの分離性を確保できます。
メッセージング システムを仮想マシンにデプロイするときは、それらの仮想マシンをコンピューティング リソースと併置して、ネットワーク待ち時間を抑える必要があります。 これらの仮想マシンは他のサービスまたはアプリケーションと共有しないようにして、メッセージング インフラストラクチャと他のシステムによるシステム リソース (CPU、メモリ、ネットワーク帯域幅など) の取り合いを回避する必要があります。 仮想マシンは可用性ゾーンに分散することもできます。そうすることで、メッセージング システムなど、ビジネスクリティカルなワークロードのリージョン内の回復性と信頼性が高まります。 たとえば、RabbitMQ や Apache ActiveMQ など、メッセージング システムを仮想マシン上にホストすることを決めたとします。 この場合、それを仮想マシン スケール セットにデプロイし、メトリック (CPU やメモリなど) に基づいて自動スケーリングするよう構成することをお勧めします。 そうすれば、メッセージング システムをホストするエージェント ノードの数が、トラフィックの状態に基づいて適切にスケールアウトおよびスケールインするようになります。 詳細については、「Azure 仮想マシン スケール セットでの自動スケールの概要」を参照してください。
Kubernetes クラスター上にメッセージング システムをホストする場合も同様に、うるさい隣人の問題を回避するため、ノード セレクターとテイントを使用して、他のワークロードと共有されていない専用ノード プールでポッドの実行をスケジュールすることを検討してください。 メッセージング システムをゾーン冗長 AKS クラスターにデプロイする場合、ポッド トポロジの分散制約を使用して、リージョン、可用性ゾーン、ノードなどの障害ドメイン間でポッドを AKS クラスター全体に分散する方法を制御します。 サードパーティのメッセージング システムを AKS にホストする場合は、Kubernetes の自動スケーリングを使用して、トラフィックが増加したときにワーカー ノードの数を動的にスケールアウトします。 Horizontal Pod Autoscaler と AKS クラスター オートスケーラーを使用すると、ノードとポッドのボリュームがトラフィックの状態に合わせてリアルタイムで動的に調整され、キャパシティの問題によって生じるダウンタイムを回避することができます。 詳細については、「Azure Kubernetes Service (AKS) でのアプリケーションの需要を満たすようにクラスターを自動的にスケーリング」を参照してください。 Kubernetes でホストされたメッセージング システム (RabbitMQ や Apache ActiveMQ など) のポッドの数を指定のキューの長さに応じてスケールアウトしたい場合は、Kubernetes イベントドリブン自動スケーリング (KEDA) の使用を検討してください。 KEDA を使用すると、処理の必要なイベントの数に基づいて Kubernetes 内のコンテナーのスケーリングを促進できます。 たとえば、KEDA を使用し、Azure Service Bus キュー、RabbitMQ キュー、ActiveMQ キューの長さに基づいてアプリケーションをスケーリングできます。 KEDA の詳細については、「Kubernetes イベントドリブン自動スケーリング」を参照してください。
分離:
マルチテナント ソリューション用のメッセージング システムを設計するときは、さまざまなタイプのアプリケーションにさまざまな種類の分離が必要であることを考慮する必要があります。これは、テナントのパフォーマンス、プライバシー、監査の各要件に基づきます。
- 複数のテナントが、同じメッセージング システムの同じメッセージング エンティティ (キュー、トピック、サブスクリプションなど) を共有できる。 たとえば、あるマルチテナント アプリケーションが、1 つの Azure Service Bus キューから、複数のテナント用のデータを保持するメッセージを受信できるとします。 このソリューションはパフォーマンスとスケーラビリティの問題を引き起こすおそれがあります。 一部のテナントが他のものよりボリュームの大きい注文を生成すると、メッセージのバックログが発生する可能性があります。 この問題は、うるさい隣人の問題とも呼ばれ、待ち時間という点で一部のテナントのサービス レベル アグリーメントを低下させる可能性があります。 問題がより明白になるのは、コンシューマー アプリケーションが厳密な時系列順でキューからメッセージを 1 つずつ読み取って処理する場合と、メッセージの処理に必要な時間がペイロード内の項目の数に依存する場合です。 複数のテナント全体で 1 つまたは複数のキュー リソースを共有する場合、メッセージング インフラストラクチャと処理システムは、スケールとスループットの要件に基づいて予想されるトラフィックに対応できる必要があります。 このアーキテクチャ アプローチは、マルチテナント ソリューションがすべてのテナントのメッセージを受信、処理、送信するためにワーカー プロセスに単一のプールを採用するシナリオに適しています。
- 複数のテナントが同じメッセージング システムを共有するものの、異なるトピックまたはキュー リソースを使用する。 このアプローチでは、より優れた分離とデータ保護を実現できます。システム管理者がプロビジョニング、監視、メンテナンスしなければならないキュー リソースの数が多くなるため、コストが大きくなり、運用の複雑さが増し、機敏性が低下します。 このソリューションを使用すると、パフォーマンスとサービス レベル アグリーメントという点において、すべてのテナントで一貫性と予測性のあるエクスペリエンスを確保できます。これは、あるテナントが他のテナントに影響し得るボトルネックになることがないためです。
- テナントごとに個別の専用メッセージング システムが使用される。 たとえば、マルチテナント ソリューションでテナントごとに個別の Azure Service Bus 名前空間を使用できます。 このソリューションを使用すると、最大限度の分離を実現できますが、複雑さと運用コストは高くなります。 このアプローチでは、一貫したパフォーマンスを保証できるほか、特定のテナントのニーズに基づいてメッセージング システムを微調整できます。 新しいテナントがオンボードされると、プロビジョニング アプリケーションは、完全に専用のメッセージング システムのほかに、新しく作成された名前空間にアクセスするための適切な RBAC アクセス許可を備えた個別のマネージド ID またはサービス プリンシパルも作成する必要があります。 たとえば、Kubernetes クラスターが同じ SaaS アプリケーションの複数のインスタンスによって共有される場合 (テナントごとに 1 つ、それぞれ別個の名前空間で実行)、各アプリケーション インスタンスでは、異なるサービス プリンシパルまたはマネージド ID を使用して専用メッセージング システムにアクセスできます。 このコンテキストでは、メッセージング システムは、フルマネージドの PaaS サービス (Azure Service Bus 名前空間) や、Kubernetes でホストされたメッセージング システム (RabbitMQ) の場合があります。 システムからテナントを削除すると、アプリケーションは、メッセージング システムと、テナント用に優先して作成された一切の専用リソースを削除する必要があります。 このアプローチの主な欠点は、運用の複雑さが高まり、機敏性が減少するところです。これは特に、テナントの数が時間の経過に伴って増える場合に顕著です。
この他に、次の考慮事項と注意事項を確認してください。
- テナントで独自のキーを使用してメッセージの暗号化と復号化を行う必要がある場合は、マルチテナント ソリューションに、テナントごとに別個の Azure Service Bus Premium 名前空間を採用するオプションが用意されている必要があります。 詳細については、「Azure Service Bus の保存データを暗号化するためにカスタマー マネージド キーを構成する」を参照してください。
- テナントに高いレベルの回復性とビジネス継続性が必要な場合は、マルチテナント ソリューションで、geo ディザスター リカバリーと可用性ゾーンを有効にして Service Bus Premium 名前空間をプロビジョニングできる必要があります。 詳細については、「Azure Service Bus の geo ディザスター リカバリー」を参照してください。
- テナントごとに個別のキュー リソースまたは専用メッセージング システムを使用する場合は、ワーカー プロセスに個別のプールを採用して、それぞれのワーカー プロセスでデータの分離レベルを高め、複数のメッセージング エンティティを処理する複雑さを減らすことが合理的です。 処理システムの各インスタンスでは、専用メッセージング システムにアクセスするために、さまざまな資格情報を採用できます (接続文字列、サービス プリンシパル、マネージド ID など)。 このアプローチを使用すると、テナント間のセキュリティ レベルと分離性が向上しますが、ID 管理の複雑さが必然的に高くなります。
同様に、イベントドリブン アプリケーションでは異なるレベルの分離を実現できます。
- イベントドリブン アプリケーションは、単一の共有 Azure Event Hubs インスタンスを介して、複数のテナントからイベントを受信します。 新しいテナントのオンボードで専用のイベント インジェスト リソースを作成する必要がないため、このソリューションは高いレベルの機敏性を実現します。しかし、同じデータ構造の複数のテナントからのメッセージが混ざり合うため、データ保護のレベルは低くなります。
- うるさい隣人の問題を回避するためや、データ分離の要件 (イベントが他のテナントのものと混合してはならない場合) を満たしてセキュリティとデータ保護を確保するために、テナントでは専用イベント ハブか Kafka トピックを選択できます。
- テナントに高いレベルの回復性とビジネス継続性が必要な場合は、マルチテナントで、geo ディザスター リカバリーと可用性ゾーンを有効にして Event Hubs Premium 名前空間をプロビジョニングできる必要があります。 詳細については、「Azure Event Hubs geo ディザスター リカバリー」を参照してください。
- お客様が規制コンプライアンス上の理由と義務のためにイベントを Azure ストレージ アカウントにアーカイブする必要がある場合は、Event Hubs Capture が有効な専用イベント ハブを作成する必要があります。 詳細については、「Azure Event Hubs で Azure Blob Storage または Azure Data Lake Storage にイベントをキャプチャする」を参照してください。
- 単一のマルチテナント アプリケーションでは、Azure Event Grid を使用して、複数の内部および外部システムに通知を送信できます。 この場合は、コンシューマー アプリケーションごとに別個の Event Grid サブスクリプションを作成する必要があります。 お客様のアプリケーションで複数の Event Grid インスタンスを使用して多数の外部組織に通知を送信する場合、"イベント ドメイン" の使用を検討してください。これによりアプリケーションは、テナントごとに 1 つなど、イベントを数千のトピックにパブリッシュできます。 詳細については、「Event Grid トピックを管理するためのイベント ドメインについて」を参照してください。
実装の複雑さ
マルチテナント ソリューションを設計するときは、ソリューションの一部または全体の再設計が必要になるまで複雑さが増していってしまうのを避けるために、システムが中長期的にどのように発展するのかを考慮することが重要です。 この再設計は、テナントの数の増加に対処するために役立ちます。 メッセージング システムを設計するときは、次の数年に予想されるメッセージ ボリュームとテナントの増加を考慮したうえで、スケールアウトできるシステムを作成する必要があります。目的は、予測されるトラフィックに対応して、プロビジョニング、監視、メンテナンスなど、運用の複雑さを軽減することです。
テナント アプリケーションがプロビジョニングまたはプロビジョニング解除されるたびに、手動の操作を必要とせずに、ソリューションで必要なメッセージング エンティティを自動的に作成または削除する必要があります。
マルチテナント データ ソリューションについて特に懸念されるのは、お客様がサポートしているカスタマイズのレベルです。 一切のカスタマイズは、アプリケーション プロビジョニング システム (DevOps システムなど) によって自動的に構成および適用される必要があります。これは、デプロイされるアプリケーションが単一テナントであってもマルチテナントであっても、初期パラメーターのセットに基づきます。
管理と操作の複雑さ
メッセージングおよびイベント インフラストラクチャをどのように運用、監視、メンテナンスするつもりなのか、また、ご自分のマルチテナント アプローチが運用とプロセスにどのように影響するのかを、最初から計画します。 たとえば、次の可能性について考えてみましょう。
- 専用の仮想マシン セットでアプリケーションによって使用されるメッセージング システムを、テナントごとに 1 つホストすることを計画する場合があります。 その場合、それらのシステムのデプロイ、アップグレード、監視、スケールアウトは、どのように計画すればよいでしょうか。
- 同様に、自分のメッセージング システムをコンテナー化して共有の Kubernetes クラスターでホストする場合は、個別のメッセージング システムのデプロイ、アップグレード、監視、スケールアウトをどのように計画すればよいでしょうか。
- 複数のテナント全体でメッセージング システムを共有するとします。 ご自分のソリューションでテナントごとの使用状況メトリックを収集してレポートしたり、各テナントが送信または受信できるメッセージの数を抑えたりするには、どうすればよいでしょうか。
- 自分のメッセージング システムで PaaS サービス (Azure Service Bus など) を利用する場合は、次の質問を立てることをお勧めします。
- テナントによって要求される機能と分離レベル (共有または専用) に基づいて、テナントごとに価格レベルをカスタマイズするには、どうすればよいでしょうか。
- テナントごとのマネージド ID と Azure ロールの割り当てを作成して、テナントがアクセスできるメッセージング エンティティ (キュー、トピック、サブスクリプションなど) のみに適切なアクセス許可を割り当てるには、どうすればよいでしょうか。 詳細については、「Azure Service Bus リソースにアクセスするために Microsoft Entra ID を使用してマネージド ID を認証する」を参照してください。
- テナントを別の種類のメッセージング サービス、別のデプロイ、別のリージョンに移動する必要がある場合、どのようにそれらを移行しますか。
[コスト]
一般的に、お使いのデプロイ インフラストラクチャに対するテナントの密度が高いほど、そのインフラストラクチャのプロビジョニング コストは低くなります。 ただし、インフラストラクチャを共有すると、うるさい隣人の問題のような課題が発生する可能性が高くなるため、そのトレードオフを慎重に検討してください。
考慮すべきアプローチとパターン
マルチテナントのメッセージング システムには、Azure アーキテクチャ センターにあるクラウド設計パターンをいくつか適用できます。 1 つまたは複数のパターンに一貫して従うことも、ニーズに基づいてパターンの併用と組み合わせを検討することもできます。 たとえば、自分のほとんどのテナントにマルチテナント Service Bus 名前空間を使用する場合がありますが、そのうえで、分離とパフォーマンスの点で料金または要件が高いテナントのために専用の単一テナント Service Bus 名前空間をデプロイすることがあります。 同様に、スタンプ内でマルチテナント Service Bus 名前空間または専用名前空間を使用する場合でも、デプロイ スタンプを使用してスケーリングする方法が適切なことがよくあります。
デプロイ スタンプ パターン
デプロイ スタンプ パターンとマルチテナントの詳細については、「マルチテナントのアーキテクチャ アプローチ」の「デプロイ スタンプ パターン」セクションを参照してください。 テナント モデルの詳細については、「マルチテナント ソリューションに対して考慮すべきテナント モデル」を参照してください。
共有メッセージング システム
共有メッセージング システム (Azure Service Bus など) をデプロイして、それをすべてのテナント間で共有することを検討する場合があります。
このアプローチを使用すると、インフラストラクチャに対するテナントの密度が最も高くなるため、総保有コストを全体的に削減できます。 また、管理とセキュリティ確保のためのメッセージング システムまたはリソースが 1 つなので、管理オーバーヘッドが軽減されることもよくあります。
ただし、複数のテナントの間でリソースまたはインフラストラクチャ全体を共有する場合は、次の注意事項を考慮してください。
- 問題となるリソースの制約、スケーリング機能、クォータ、制限について常に留意、考慮してください。 たとえば、Azure サブスクリプションにおける Service Bus 名前空間の最大数、単一の名前空間における Event Hubs の最大数、または最大スループット上限は、アーキテクチャが成長して多くのテナントをサポートするようになると、最終的に大きな阻害要因になる可能性があります。 1 つの Azure サブスクリプションあたりの名前空間、または 1 つの名前空間あたりのキューの数という点で達成する必要がある最大スケールを注意深く検討してください。 さらに、このパターンを選択する前に、現在および将来の見積もりを、お好みのメッセージング システムの既存のクォータおよび制限と比較してください。
- 上のセクションで言及したように、複数のテナント全体でリソースを共有するとき、特に一部が非常にビジーである場合またはそれらが他のものよりも高いトラフィックを生成する場合に、うるさい隣人の問題が要因になる可能性があります。 その場合、これらの影響を軽減するために、調整パターンまたはレート制限パターンの適用を検討します。 たとえば、単一のテナントが単位時間あたりに送受信できるメッセージの最大数を制限できます。
- 単一のテナントの場合、アクティビティの監視とリソース使用量の測定が困難な場合があります。 一部のサービス (Azure Service Bus など) では、メッセージング操作に対して料金が発生します。 そのため、複数のテナント全体で名前空間を共有する場合、アプリケーションは、各テナントのために行われるメッセージング操作の数と、それらに対するチャージバック コストを継続して追跡できる必要があります。 一方で、同じレベルの詳細情報を提供していないサービスもあります。
テナントには、セキュリティ、リージョン内の回復性、ディザスター リカバリー、または場所についのさまざまな要件がある場合があります。 これらは、メッセージング システムの構成に一致しないと、単一のリソースだけでは対応できない可能性があります。
シャーディング パターン
シャーディング パターンでは、複数のメッセージング システムのデプロイを行います ("シャード" と呼ばれる)。これには、1 つまたは複数のテナントのメッセージング エンティティ (キューやトピックなど) 含まれています。 デプロイ スタンプとは異なり、シャードは、インフラストラクチャ全体が重複していることを意味するものではありません。 ご自身のソリューション内で他のインフラストラクチャを複製またはシャード化せずに、メッセージング システムをシャード化できます。
すべてのメッセージング システムまたは "シャード" は、信頼性、SKU、場所という点で特性が異なる場合があります。 たとえば、パフォーマンス、信頼性、データ保護、またはビジネス継続性の観点から場所またはニーズに基づいて、特性が異なる複数のメッセージング システム全体でテナントをシャード化できます。
シャーディング パターンを使用する際は、特定のテナントをそのキューが含まれているメッセージング システムにマップするために、シャーディング戦略を使用する必要があります。 Lookup 戦略ではマップを使用し、テナントの名前または ID に基づいてターゲット メッセージング システムを個別化します。 複数のテナントで同じシャードを共有する可能性はありますが、1 つのテナントによって使用されるメッセージング エンティティが複数のシャードにまたがることはありません。 マップは、テナントの名前をターゲット メッセージング システムの名前または参照にマップする単一のディクショナリを使用して実装できます。 マップは、マルチテナント アプリケーションのすべてのインスタンスからアクセスできる分散キャッシュ、または永続ストア (リレーショナル データベース内のテーブルやストレージ アカウント内のテーブル) に保存できます。
シャーディング パターンは、多数のテナントに合わせてスケーリングできます。 さらに、ワークロードによっては、シャードに対するテナントの密度を高くできる場合があるため、コスト面でも魅力的です。 また、シャーディング パターンを使用して、Azure サブスクリプションとサービスのクォータ、制限、制約に対応することもできます。
テナントごとに専用のメッセージング システムがあるマルチテナント アプリ
1 つのマルチテナント アプリケーションを、テナントごとに専用メッセージング システムを用意してデプロイするアプローチも一般的です。 このテナント モデルでは、コンピューティング リソースなど、いくつかの共有コンポーネントがある一方で、その他のサービスはプロビジョニングされ、単一テナントの専用デプロイ アプローチを使用して管理されます。 たとえば、次に示すように、1 つのアプリケーション層を構築してから、テナントごとに個別のメッセージング システムをデプロイすることができます。
システムの負荷の大部分が、テナントごとに個別にデプロイできる特定のコンポーネントによって発生していることが判明した場合、水平方向にパーティション分割されたデプロイを使用してうるさい隣人の問題を軽減することができます。 たとえば、単一のインスタンスでは複数のテナントによって生成されるトラフィックに対応するうえで不十分なため、テナントごとに別個のメッセージングまたはト ストリーミング システムを使用することが必要な場合があります。 テナントごとに専用のメッセージング システムを使用している場合、単一のテナントで大量のメッセージまたはイベントが生成されると、共有コンポーネントには影響が出る可能性があるものの、その他のテナントのメッセージング システムには影響ありません。
テナントごとに専用リソースをプロビジョニングするため、このアプローチのコストは、共有ホスティング モデルよりも高くなる可能性があります。 他方で、このテナント モデルを採用する場合は、専用システムのリソース コストを、それを利用する固有のテナントにチャージバックすることが容易になります。 このアプローチでは、その他のサービス (コンピューティング リソースなど) に対して高い密度を実現できるので、それらのコンポーネントのコストが低下します。
水平方向にパーティション分割されたデプロイがあると、マルチテナント アプリケーションのサービス (特に単一のテナントによって使用されるもの) をデプロイして管理するために、自動化されたプロセスを採用する必要があります。
Geodes パターン
ジオード パターンでは、一連の地理的ノードにバックエンド サービスのコレクションをデプロイします。 それぞれ、どのリージョンにあるどのクライアントに対するどの要求でも処理できます。 このパターンでは、アクティブ/アクティブ スタイルで要求を処理できます。これにより、要求の処理が世界中に分散され、待ち時間が改善し、可用性が向上します。
Azure Service Bus と Azure Event Hubs では、最善のリージョン内の復性をサポートするために、プライマリとセカンダリのディザスター リカバリー名前空間全体、および個別のリージョンと可用性ゾーン全体でメタデータのディザスター リカバリーをサポートしています。 さらに、Azure Service Bus と Azure Event Hubs では、同じ論理トピック、キュー、またはイベント ハブをアクティブにレプリケートして複数の名前空間で利用可能にし、最終的に異なるリージョンに配置する一連のフェデレーション パターンを実装します。 詳細については、次のリソースを参照してください。
- メッセージ レプリケーションとリージョン間フェデレーション
- メッセージ レプリケーション タスクのパターン
- マルチサイトとマルチリージョンのフェデレーション
- イベント レプリケーション タスクのパターン
共同作成者
この記事は、Microsoft によって保守されています。 当初の寄稿者は以下のとおりです。
プリンシパル作成者:
- Paolo Salvator | FastTrack for Azure のプリンシパル カスタマー エンジニア
その他の共同作成者:
- John Downs | プリンシパル ソフトウェア エンジニア
- Clemens Vasters | プリンシパル アーキテクト、メッセージング サービスと標準
- Arsen Vladimirskiy | FastTrack for Azure のプリンシパル カスタマー エンジニア
次のステップ
メッセージングの設計パターンの詳細については、次のリソースを参照してください。