アプリケーションをスケーラブルにする
成長に備えることの基本を理解し、容量計画で考慮する要因について知っているので、アプリケーションを可能な限りスケーラブルなものにするという課題に着手することができます。
アーキテクチャ レビュー
重要な点は、システムについて、通常のアーキテクチャ レビューを実行する必要があると覚えておくことです。
コードとしてのインフラストラクチャなどの実施方法を適用して、クラウド リソースのデプロイ方法を改善できることを認識しています。 アプリケーション コードを定期的に更新して改善します。また、基になっているプラットフォーム リソースでも同じことを行う必要があります。
アーキテクチャ レビューを実行すると、改善が必要な領域を特定するのに役立ちます。
Azure アーキテクチャ センターには、クラウドでのアプリケーションの設計に役立つ豊富なリソースが用意されています。また、以下のリンクのアプリケーション アーキテクチャ ガイドには、スケーラビリティに関する推奨事項が多数収録されています。
シナリオ: Tailwind Traders のアーキテクチャ
最初の手順は、アーキテクチャとアプリケーションの評価を行うことです。これは、弱点がある場所を特定するだけでなく、それらの長所も認識するためのものです。 それは何が良いのでしょうか。
前のユニットで見たシナリオをもう一度見てください。 次に、もう一度組織のアーキテクチャ図を示します。
アプリケーションはより小さなマイクロサービスに分解されており、これらのサービスの一部が、Azure Kubernetes Service 上のコンテナーとして配置されています。または、それらは VM または App Service で実行されている可能性があります。 Functions や Logic Apps など、"本質的にスケーラブル" なサービスをいくつか使用しています。
この変更は適切ですが、アプリケーションをよりスケーラブルにする機能強化がいくつか存在します。 例として、ここでは "製品" サービスに注目します。 この図では、製品サービスは Kubernetes で実行されていますが、この説明では、Azure 内の VM で実行中であると想定します。 スケーリングの概念は、おそらくわずかに異なる実装により、実行されている場所がサーバーか、App Service か、コンテナーかを問わず、アプリケーションに適用できます。
この製品は現在、単一の Azure SQL データベースに接続された 1 つの VM で実行されています。 この VM でスケールアウトを有効にする必要があります。これは Azure Virtual Machine Scale Sets を使用して行えます。それにより、まったく同じ、負荷分散される VM のグループを作成して管理できます。 現在は複数の VM があるため、VM 間でトラフィックを分散させるロード バランサーを導入する必要があります。
仮想マシン スケール セット
1 つの VM に対して Virtual Machine Scale Sets を適用することには、いくつかの利点があります。
- ホスト メトリック、ゲスト内メトリック、アプリケーションの分析情報、またはスケジュールに基づく自動スケールが可能です。
- Azure リージョン内の独立したスタンドアロン データセンターである Availability Zones (AZ) を使用できます。 AZ がサポートされていると、複数の AZ にわたって VM を分散させることができます。これにより、アプリケーションの信頼性が向上し、データセンターの障害から保護されます。 スケール セット内の新しいインスタンスは、自動的に、AZ 間にわたって均等に分散されます。
- ロード バランサーの追加が簡単になっています。 仮想マシン スケール セットでは、基本レイヤー 4 のトラフィック分散に対して Azure Load Balancer の使用がサポートされています。 また、より高度な L7 のトラフィック分散と SSL 終了に対して Azure Application Gateway もサポートされています。
スケール セットを実装する前に考慮する必要がある重要な要因がいくつかあります。 具体的には:
- インスタンスの "持続性" を避けて、特定のバックエンドに "スタックされた" クライアントがないようにします。
- 永続的なデータを VM から削除し、それを Azure Storage やデータベースなど、その他の場所に格納します。
- スケールインに向けた設計。 アプリケーションでスケール ダウンを簡単に処理できることも重要です。 トラフィックを処理するサーバーのプールに追加されるインスタンスを増やすことだけでなく、負荷が減少したときにインスタンスが突然終了することも、適切に処理する必要があります。 スケーリングに関するスケールダウンの側面は見落とされることがよくあります。
分離
スケール セットを使用してより多くの VM を追加しました。 スケールアウトは、"スケーリングする必要がある" 状況に対する一般的な対処法ですが、スケーリングできるのは 1 つのメトリックに対してのみであり、製品サービスによって実行中のすべてのタスクに対して、この対処法が適切であるとは限りません。
このシナリオでは、製品サービスにはジョブが 1 つあります。 製品イメージの取得後、イメージがアップロードされます。 そのイメージがトランスコードされ、サムネイルやカタログの写真などのためにいくつかの異なるサイズで保存されます。 イメージ処理では CPU が集中的に使われますが、一般的な使用状況ではメモリが集中的に消費されます。
イメージ処理は、バックグラウンド ジョブに分割できる非同期タスクです。 これを行うには、キューを使用してイメージ処理サービスを分離します。 分離することで、両方のサービスを個別にスケーリングできます (1 つはメモリ上で (製品サービス)、もう 1 つは CPU 上またはキュー長に対して (処理サービス))。また、別のスケール セットでそれらのメッセージを使用し、イメージを処理できるようになります。
キューでのスケーリング
Azure には、次の 2 種類のキュー オファリングがあります。
- Azure Service Bus キュー: より広範な Azure Service Bus 製品に含まれる、より高度なキュー オファリングであり、パブリッシュ/サブスクライブおよびより高度な統合パターンを提供します。
- Azure Storage Queues: Azure Storage 上に構築されたシンプルな REST ベースのキュー インターフェイスです。 これにより信頼性の高い永続的なメッセージングが提供されます。
このシナリオでの要件は単純であるため、Azure Storage のキューを使用できます。 このバックグラウンド タスクは分離済みであるため、製品層はまったくスケーリングする必要はありません。
メモリ内キャッシュ
アプリケーションのパフォーマンスを向上させる別の方法は、メモリ内キャッシュを実装することです。
パフォーマンスが厳密にスケーラビリティと等しいわけではないことはわかっていますが、アプリケーションのパフォーマンスを向上させることで、他のリソースでの負荷を軽減できます。 こうした向上があることは、すぐにスケーリングする必要はない可能性があることを意味します。
Azure Cache for Redis は、Redis のマネージド オファリングです。 Redis は、さまざまなパターンやユース ケースに使用できます。 このシナリオの製品サービスについては、おそらくキャッシュ アサイド パターンを実装することになります。 このパターンでは、必要に応じてデータベースからキャッシュに項目を読み込むことで、アプリケーションのパフォーマンスを向上させ、データベースでの負荷を軽減します。
Redis は、Web コンテンツのキャッシュまたはユーザー セッションのキャッシュのために、メッセージング キューとして使用することもできます。 この種類のキャッシュは、ショッピング カート サービスなど、システム内の他のサービスにより適している可能性があります。この場合、Cookie を使用する代わりに、Redis 内でセッションごとにショッピング カート データを保存することができます。
データベースをスケーリングする
コンピューティング リソースをよりスケーラブルにしたので、データベースについて調べます。 このシナリオでは、Azure SQL データベースを使用しています。これは、Azure からの SQL サーバーのマネージド オファリングです。
リレーショナル データベースは、非リレーショナル データベースよりもスケールアウトが困難です。 データベースをスケーリングするために行う可能性がある最初のことは、データベースのサイズをスケールアップすることです。 このサイズ変更は、平均 4 秒以下のダウンタイムで簡単に行うことができます。 Azure SQL で単純な API 呼び出しを使用するか、ポータルでスライダーを使用します。
このサイズ拡大が要件を満たさない場合、トラフィックの特性によっては、データベースに対する読み取りをスケールアウトする方が適切である可能性があります。 読み取りトラフィックを読み取りレプリカにルーティングできるようになります。
注意
Azure SQL では、サービス レベルとして Premium または Business Critical を使用している場合、読み取りのスケールアウトが既定で有効になります。 Basic または Standard のサービス レベルでは有効にできません。
この変更は、コードで実装する必要があります。 以下に、それを実行する方法を示します。
#Azure SQL Connection String
#Master Connection String
ApplicationIntent=ReadWrite
#Read Replica Connection String
ApplicationIntent=ReadOnly
#Full Example
Server=tcp:<server>.database.windows.net;Database=<mydatabase>;ApplicationIntent=ReadOnly;User ID=<myLogin>;Password=<myPassword>;Trusted_Connection=False; Encrypt=True;
データベース接続文字列の ApplicationIntent
属性を更新して、接続先にするサーバーを指定します。 レプリカに接続する場合は ReadOnly
を使用し、マスターに接続する場合は ReadWrite
を使用します。
このコマンドはコードで実装する必要があるため、お客様の状況に適した解決策ではない可能性があります。 一つ一つの製品サービスで読み取りと書き込みの機能が必要な場合は、どうすればよいでしょうか。
その場合は、シャーディングを使用して SQL DB をスケールアウトする方法を確認できます。
データベース シャーディング
読み取りレプリカをスケール アップまたは実装した後もデータベース リソースがシステムのニーズを満たしていない場合、次のオプションはシャーディングです。
シャーディングとは、同じ構造を持つ大量のデータを、多数の独立したデータベースにわたって分散させる手法です。 シャーディングは、さまざまな理由で必要になる場合があります。 以下に例を示します。
- データの総量が大きすぎて、個々のデータベースの制約内に収まりません。
- ワークロード全体のトランザクション スループットが、個々のデータベースの機能を超過しています。
- コンプライアンス上の理由で、個々のテナントを物理的に異なるデータベース上に置く必要があります (この要件は、スケーリングについては少数ですが、シャーディングが使用される別の状況です)。
アプリケーションによって、関連性のあるデータが関連性のあるシャードに追加されるため、システムは個々のデータベースの制約を超えてスケーラブルになります。
Azure SQL では、Azure Elastic Database ツールを提供しています。 これらのツールは、アプリケーション ロジックから Azure 内のシャード SQL データベースを作成、管理、およびクエリするのに役立ちます。