デプロイ スタンプ パターンには、複数のワークロードまたはテナントをホストおよび運用するための異種リソース グループのプロビジョニング、管理、監視が含まれます。 個々のコピーはスタンプと呼ばれ、サービス ユニット、スケール ユニット、またはセルと呼ばれる場合もあります。 マルチテナント型の環境では、すべてのスタンプ、つまりスケール ユニットは、定義済みの数のテナントにサービスを提供できます。 複数のスタンプをデプロイして、ソリューションをほぼ直線的にスケーリングし、増加するテナントにサービスを提供できます。 このアプローチにより、ソリューションのスケーラビリティが向上し、インスタンスを複数のリージョンにデプロイすることが可能となり、顧客データを分離できます。
Note
Azure でのマルチテナント型ソリューションの設計の詳細は、「Azure でのマルチテナント型ソリューションを設計」を参照してください。
コンテキストと問題
クラウドでアプリケーションをホストする場合は、アプリケーションのパフォーマンスと信頼性を考慮することが重要です。 ソリューションの単一インスタンスをホストする場合、次の制限事項が適用されます。
- スケールの制限: アプリケーションの単一インスタンスをデプロイすると、スケーリングの自然な制限が生じる可能性があります。 たとえば、受信接続、ホスト名、TCP ソケット、その他のリソースの数に制限があるサービスを使用する可能性があります。
- 非線形のスケーリングまたはコスト: ソリューションの一部のコンポーネントが、要求数やデータ量に応じて直線的にスケーリングされない場合があります。 代わりに、しきい値に達すると、パフォーマンスが突然低下したり、コストが増加したりする可能性があります。 たとえば、データベースを使用しているときに、容量の追加 (スケールアップ) の限界コストが非常に高くなることに気付き、スケールアウトの方がコスト効率の高い戦略であることがわかる場合があります。
- 顧客の分離: 特定の顧客のデータを他の顧客のデータから分離しておくことが必要な場合があります。 同様に、サービスを提供するために、他の顧客よりも多くのシステム リソースを必要とする顧客がいる場合があります。この場合、それらの顧客をインフラストラクチャの別のセットにグループ化することを検討します。
- シングルテナントおよびマルチテナント型のインスタンスへの対応。 ソリューションの独自の独立したインスタンスを必要とする大規模な顧客がいる場合があります。 また、マルチテナント型のデプロイを共有できる小規模な顧客のグループがある場合もあります。
- 複雑なデプロイ要件: 制御された方法でサービスに更新プログラムを展開したり、顧客ベースのサブセットごとに異なるタイミングで展開したりすることが必要な場合があります。
- 更新頻度: システムの頻繁な更新を許容する顧客もいれば、リスクを嫌い、要求を処理するシステムが頻繁に更新されないことを望む顧客もいます。 これらの顧客を分離された環境にデプロイするのが合理的と考えられます。
- 地理的または地政学的な制約: 低待機時間を考慮して設計するためや、データの主権要件に準拠するために、一部の顧客を特定のリージョンにデプロイすることがあります。
これらの制限は、多くの場合、マルチテナント向けに設計されているサービスとしてのソフトウェア (SaaS) を構築する独立系ソフトウェア ベンダー (ISV) に適用されます。 ただし、他のシナリオにも同じ制限が適用される場合があります。
解決策
これらの問題を回避するには、リソースを "スケール ユニット" にグループ化し、"スタンプ" の複数のコピーをプロビジョニングすることを検討してください。 各 "スケール ユニット" は、テナントのサブセットをホストし、サービスを提供します。 スタンプは互いに独立して動作するので、個別にデプロイして更新できます。 1 つの地理的リージョンに、1 つのスタンプを含めることも、リージョン内で水平方向にスケールアウトできるように複数のスタンプを含めることもできます。 スタンプには顧客のサブセットが含まれます。
ソリューションで使用しているのが、IaaS (サービスとしてのインフラストラクチャ) コンポーネント、PaaS (サービスとしてのプラットフォーム) コンポーネント、これらの組み合わせのいずれであっても、デプロイ スタンプを適用できます。 通常、IaaS ワークロードはスケーリングするためにより多くの介入を必要とするため、IaaS の負荷が高いワークロードでスケールアウトを可能にするために、このパターンが役立つことがあります。
スタンプを使用して、デプロイ リングを実装できます。 顧客がそれぞれ異なる頻度でサービスの更新プログラムを受け取ることを希望している場合は、顧客をさまざまなスタンプにグループ化し、スタンプごとに異なる頻度で更新プログラムを展開できます。
スタンプは互いに独立して実行されるため、データは暗黙的に "シャード化" されます。 また、1 つのスタンプでさらにシャーディングを使用することで、そのスタンプ内でスケーラビリティと弾力性を内部的に実現できます。
デプロイ スタンプ パターンは、App Service、Azure Stack、Azure Storage など、多くの Azureサービスで内部的に使用されています。
デプロイ スタンプは、Geode と関連していますが、これとは異なります。 デプロイ スタンプ アーキテクチャでは、システムの独立したインスタンスが複数デプロイされ、顧客とユーザーのサブセットが含まれます。 Geode では、すべてのインスタンスがすべてのユーザーからの要求を処理できますが、このアーキテクチャは、多くの場合、設計と構築がより複雑になります。 また、2 つのパターンを 1 つのソリューションに混在させることも検討できます。この記事で後述するトラフィック ルーティングアプローチでは、このハイブリッド シナリオの例について説明します。
展開
同じコンポーネントの同一コピーのデプロイには複雑さが伴うため、このパターンの実装を確実に成功させるには、優れた DevOps プラクティスが不可欠となります。 Bicep、JSON Azure Resource Manager テンプレート (ARM テンプレート)、Terraform、およびスクリプトなどを使用して、インフラストラクチャをコードとして記述することを検討してください。 この方法を使用すると、各スタンプのデプロイが予測可能で再現性のあるものになります。 また、不注意によるスタンプ間の構成の不一致などの人為的なミスの可能性も低減されます。
更新プログラムをすべてのスタンプに自動的に並列展開できます。その場合、インフラストラクチャとアプリケーションのデプロイを調整するために、Bicep や Resource Manager テンプレートなどのテクノロジを検討します。 または、一部のスタンプに更新プログラムを徐々にロールアウトしてから、他のスタンプに段階的にロールアウトしていくこともできます。 Azure Pipelines や GitHub Actions などのリリース管理ツールを使用して、各スタンプへのデプロイを調整することを検討してください。 詳細については、次を参照してください。
デプロイについては、Azure サブスクリプションとリソース グループのトポロジを慎重に検討してください。
- 通常、サブスクリプションには 1 つのソリューションのすべてのリソースが含まれるため、一般に、すべてのスタンプに単一のサブスクリプションを使用することを検討します。 ただし、一部の Azure サービスではサブスクリプション レベルのクォータが適用されるので、このパターンを使用して高度なスケールアウトを可能にする場合は、複数の異なるサブスクリプションにスタンプをデプロイすることを検討する必要があります。
- リソース グループは、同じライフサイクルでコンポーネントをデプロイするために一般的に使用されます。 一度にすべてのスタンプに更新プログラムを展開する場合は、単一のリソース グループを使用してすべてのスタンプのすべてのコンポーネントを含め、リソースの名前付け規則とタグを使用して、各スタンプに属するコンポーネントを識別することを検討します。 また、各スタンプに更新プログラムを個別に展開する場合は、スタンプをそれぞれ独自のリソース グループにデプロイすることを検討します。
容量計画
ロード テストとパフォーマンス テストを使用して、特定のスタンプが対応できるおおよその負荷を測定します。 負荷メトリックは、1 つのスタンプが対応できる顧客数/テナント数、またはスタンプ内のコンポーネントが生成するサービスからのメトリックに基づいている場合があります。 特定のスタンプがその容量に近づく時期を見積もるための十分なインストルメンテーションがあり、新しいスタンプを迅速にデプロイして需要に対応できることを確認します。
トラフィックのルーティング
デプロイ スタンプ パターンは、各スタンプが個別にアドレス指定されている場合に効果的に機能します。 たとえば、Contoso が同じ API アプリケーションを複数のスタンプにデプロイする場合、DNS を使用して適切なスタンプにトラフィックをルーティングすることを検討できます。
unit1.aus.myapi.contoso.com
では、オーストラリア リージョン内のスタンプunit1
にトラフィックをルーティングします。unit2.aus.myapi.contoso.com
では、オーストラリア リージョン内のスタンプunit2
にトラフィックをルーティングします。unit1.eu.myapi.contoso.com
では、ヨーロッパ リージョン内のスタンプunit1
にトラフィックをルーティングします。
その後、各クライアントが適切なスタンプに接続する必要があります。
すべてのトラフィックの単一のイングレス ポイントが必要な場合は、トラフィック ルーティング サービスを使用して、特定の要求、顧客、またはテナントのスタンプを解決できます。 トラフィック ルーティング サービスは、スタンプの適切な URL にクライアントを転送します (たとえば、HTTP 302 応答状態コードを使用)。または、リバース プロキシとして機能し、クライアントが認識していなくても、適切なスタンプにトラフィックを転送することもできます。
特に、ソリューションが複数のリージョンで実行される場合、一元化されたトラフィック ルーティング サービスは、設計が複雑なコンポーネントになる可能性があります。 トラフィック ルーティング サービスを複数のリージョン (スタンプがデプロイされているすべてのリージョンを含む可能性があります) にデプロイすることを検討し、データ ストア (テナントをスタンプにマッピング) が確実に同期されるよう考慮します。 トラフィックルーティングコンポーネント自体がジオデパターンのインスタンスである可能性があります。
たとえば、Azure API Management をデプロイして、トラフィック ルーティング サービス ロールとして機能させることができます。 API Management では、テナントとスタンプ間のマッピングを保存する Azure Cosmos DB コレクション内のデータを参照することで、要求に適したスタンプを特定できます。 その後、バックエンド URL を適切なスタンプの API サービスに動的に設定できます。
要求の geo ディストリビューションとトラフィック ルーティング サービスの geo 冗長性を実現するために、API Management を複数のリージョンにデプロイすることも、Azure Front Door を使用してトラフィックを最も近いインスタンスに転送することもできます。 Front Door はバックエンド プールで構成できるので、要求を最も近い利用可能な API Management インスタンスに転送できます。 アプリケーションが HTTP/S 経由で公開されていない場合は、リージョン間 Azure Load Balancer を使用して、着信呼び出しをリージョンの Azure Load Balancer に分散できます。 Azure Cosmos DB のグローバル分散機能を使用して、各リージョンでマッピング情報を最新の状態に保つことができます。
トラフィック ルーティング サービスがソリューションに含まれている場合は、ゲートウェイとして機能するかどうかを検討します。ゲートウェイとして機能すると、トークンの検証、調整、承認などの他のサービスに対してゲートウェイ オフロードを実行できます。
トラフィック ルーティング アーキテクチャの例
次のトラフィック ルーティング アーキテクチャの例を考えてみます。このアーキテクチャでは、Azure Front Door、Azure API Management、Azure Cosmos DB を使用してグローバルなトラフィック ルーティングを行い、一連のリージョン固有のスタンプを使用します。
あるユーザーが、通常ニューヨークに在住しているとします。 データは、米国東部リージョンのスタンプ 3 に格納されます。
このユーザーがカリフォルニアに移動してシステムにアクセスした場合、その接続は米国西部 2 リージョンを経由してルーティングされる可能性があります。これは、要求を行ったときの地理的な位置に最も近いためです。 ただし、要求は最終的にはスタンプ 3 で処理される必要があります。なぜなら、データが格納される場所だからです。 トラフィック ルーティング システムによって、要求が正しいスタンプにルーティングされることが保証されます。
問題と注意事項
このパターンの実装方法を決めるときには、以下の点に注意してください。
- デプロイ プロセス: 複数のスタンプをデプロイするときは、自動化された完全に反復可能なデプロイ プロセスを使用することを強くお勧めします。 スタンプを宣言的に定義し、定義の一貫性を維持するために Bicep、JSON ARM テンプレート、または Terraform モジュールを使用することを検討してください。
- スタンプをまたがる操作: ソリューションが複数のスタンプに個別にデプロイされている場合、"全スタンプの顧客数はどれくらいか?" といった質問に対して回答が複雑になる可能性があります。 各スタンプに対してクエリを実行し、結果を集計することが必要な場合があります。 代わりに、すべてのスタンプでデータを集中型データ ウェアハウスに発行して、統合レポートを作成することを検討してください。
- スケールアウト ポリシーの決定: スタンプの容量には限りがあります。容量は、スタンプにデプロイできるテナントの数などのプロキシ メトリックを使用して定義できます。 各スタンプの使用可能な容量と使用済みの容量を監視し、追加のスタンプを事前にデプロイして新しいテナントを移動できるようにすることが重要です。
- スタンプの最小数。 展開スタンプ パターンを使用する場合は、ソリューションの少なくとも 2 つのスタンプをデプロイすることをお勧めします。 1 つのスタンプのみをデプロイする場合は、スケールアウト時に適用されないコードまたは構成に誤ってコードの前提条件をハードコーディングしてしまうことがあります。
- コスト。 デプロイ スタンプ パターンでは、インフラストラクチャ コンポーネントの複数のコピーをデプロイする必要があるため、ソリューションの運用コストが大幅に増加する可能性があります。
- スタンプ間の移動: 各スタンプは個別にデプロイされて運用されるため、スタンプ間でのテナントの移動が困難な場合があります。 アプリケーションには、特定の顧客に関する情報を別のスタンプに送信し、テナントの情報を元のスタンプから削除するためのカスタム ロジックが必要です。 このプロセスでは、スタンプ間の通信にバックプレーンが必要になる場合があり、ソリューション全体がさらに複雑化します。
- トラフィックのルーティング: この記事で前述したように、特定の要求に適したスタンプにトラフィックをルーティングするには、テナントをスタンプに解決するための追加コンポーネントが必要になる可能性があります。 さらに、このコンポーネントの可用性を高めることが必要になる場合があります。
- 共有コンポーネント: 一部のコンポーネントをスタンプ間で共有できる場合があります。 たとえば、すべてのテナントで共有されるシングルページ アプリがある場合は、それを 1 つのリージョンにデプロイし、Azure CDN を使用してグローバルにレプリケートすることを検討します。
このパターンを使用する状況
このパターンは次の場合に役立ちます。
- スケーラビリティの自然な制限がある場合。 たとえば、一定の顧客数または要求数を超えてスケーリングできないコンポーネントがある場合は、スタンプを使用したスケールアウトを検討します。
- 特定のテナントを他のテナントから分離する必要がある場合。 セキュリティ上の問題により、他の顧客と共にマルチテナント型のスタンプにデプロイできない顧客がいる場合は、それらの顧客を独自の分離されたスタンプにデプロイできます。
- 一部のテナントをソリューションのさまざまなバージョンに同時に配置する必要がある場合。
- 各テナントのデータとトラフィックを特定のリージョンに転送する必要があるマルチリージョン アプリケーションがある場合。
- 停止中に回復性を実現したい場合。 スタンプは互いに独立しているため、停止が 1 つのスタンプに影響を与えても、他のスタンプにデプロイされたテナントは影響を受けません。 この分離により、インシデントまたは停止の "影響範囲" を抑えることができます。
このパターンは以下には適していません。
- 高度にスケーリングする必要のないシンプルなソリューション。
- たとえば、アプリケーション レイヤーのサイズを増やしたり、データベースとストレージ層の予約容量を増やしたりすることによって、単一インスタンス内で簡単にスケールアウトまたはスケールアップできるシステム。
- デプロイされているすべてのインスタンスにデータをレプリケートする必要があるソリューション。 このシナリオでは、Geode パターンを検討してください。
- スケーリングする必要があるのは一部のコンポーネントだけであり、他のコンポーネントはスケーリングする必要がないソリューション。 たとえば、すべてのソリューション コンポーネントの新しいコピーをデプロイするのではなく、データ ストアをシャード化することによってソリューションをスケーリングできるかどうかを検討します。
- フロントエンド JavaScript アプリケーションなど、静的コンテンツだけで構成されるソリューション。 このようなコンテンツをストレージ アカウントに保存し、Azure CDN を使用することを検討します。
ワークロード設計
設計者は、Azure Well-Architected Framework の柱で説明されている目標と原則に対処するために、導入スタンプパターンをワークロードの設計でどのように使用できるかを評価する必要があります。 次に例を示します。
重要な要素 | このパターンが柱の目標をサポートする方法 |
---|---|
オペレーショナルエクセレンス は、標準化されたプロセスとチームの結束によってワークロードの品質を提供します。 | このパターンは、不変のインフラストラクチャ目標、高度な導入モデルをサポートし、安全な導入方法を容易に実現します。 - OE:05コードとしてのインフラストラクチャ - OE:11 安全な配備の実践 |
パフォーマンスの効率化は、スケーリング、データ、コードを最適化することによって、ワークロードが効率的にニーズを満たすのに役立ちます。 | このパターンは、多くの場合、ワークロードで定義されたスケールユニットに合わせて調整されます。単一のスケールユニットが提供する容量を超える容量が必要なため、拡張用に追加の展開スタンプが展開されます。 - PE:05 スケーリングとパーティショニング |
設計決定と同様に、このパターンで導入される可能性のある他の柱の目標とのトレードオフを考慮してください。
サポート テクノロジ
- コードとしてのインフラストラクチャ。 Bicep、Resource Manager テンプレート、Azure CLI、Terraform、PowerShell、Bash など。
- Azure Front Door。トラフィックを特定のスタンプまたはトラフィック ルーティング サービスにルーティングできます。
例
次の例では、シンプルな PaaS ソリューションの複数のスタンプをデプロイします。各スタンプには、アプリ サービスと SQL Database が含まれています。 スタンプは、テンプレートにデプロイされたサービスをサポートする任意のリージョンに構成できますが、説明のために、このテンプレートでは米国西部 2 リージョン内に 2 つのスタンプをデプロイし、西ヨーロッパ リージョンにもスタンプをデプロイします。 スタンプ内で、アプリ サービスは独自のパブリック DNS ホスト名を受け取り、他のすべてのスタンプから独立して接続を受信できます。
警告
次の例では、SQL Server 管理者アカウントを使用しています。 通常、アプリケーションから管理者アカウントを使用することはお勧めしません。 実際のアプリケーションでは、マネージド ID を使用してアプリケーションから SQL Database に接続するか、最小特権アカウントを使用することを検討してください。
ソリューションをデプロイするには、下のリンクをクリックします。
注意
Resource Manager テンプレートを使用してスタンプをデプロイする別の方法もあります。たとえば、入れ子になったテンプレートまたはリンクされたテンプレートを使用して、複数のコピーをデプロイするために必要な反復から各スタンプの定義を切り離します。
トラフィック ルーティング方法の例
次の例では、仮定の API アプリケーションのデプロイ スタンプ セットで使用できるトラフィック ルーティング ソリューションの実装をデプロイします。 受信要求の地理的分散を可能にするために、従量課金レベルで API Management の複数のインスタンスと共に Front Door がデプロイされます。 各 API Management インスタンスは、要求 URL からテナント ID を読み取り、地理的に分散した Azure Cosmos DB データ ストアから、要求の適切なスタンプを参照します。 その後、要求は関連するバックエンド スタンプに転送されます。
ソリューションをデプロイするには、下のリンクをクリックします。
共同作成者
この記事は、Microsoft によって保守されています。 当初の寄稿者は以下のとおりです。
プリンシパル作成者:
- John Downs | プリンシパル プログラム マネージャー
その他の共同作成者:
- Daniel Larsen | FastTrack for Azure のプリンシパル カスタマー エンジニア
- Angel Lopez | Azure Patterns と Azure Practices のシニア ソフトウェア エンジニア
- Paolo Salvator | FastTrack for Azure のプリンシパル カスタマー エンジニア
- Arsen Vladimirskiy | FastTrack for Azure のプリンシパル カスタマー エンジニア
パブリックでない LinkedIn プロファイルを表示するには、LinkedIn にサインインします。
関連リソース
- データ層をスケールアウトするためのよりシンプルな別の方法として、シャーディングを使用できます。 スタンプではデータが暗黙的にシャード化されますが、シャーディングにデプロイ スタンプは不要です。 詳細については、「シャーディング パターン」を参照してください。
- トラフィック ルーティング サービスがデプロイされている場合は、ゲートウェイ ルーティング パターンとゲートウェイ オフロード パターンを併用することで、このコンポーネントを最大限に活用できます。