Azure Functions では、1 つの関数アプリ インスタンスを使用して、複数のイベントを同時に処理できます。 これらは同じコンピューティング インスタンスで実行されるため、メモリ、CPU、接続リソースを共有します。 特定のホスティング プランでは、特定のインスタンスに対する需要が高いため、Functions ホストは負荷の増加に対応する新しいインスタンスを自動的に作成します。 これらの 動的スケール プランでは、コンカレンシー動作とスケーリング動作の間にトレードオフがあります。 アプリの実行方法をより詳細に制御するために、Functions には同時実行の数を管理する方法が用意されています。
Functions には、コンカレンシーを管理する主に 2 つの方法が用意されています。
- インスタンスごとのコンカレンシーを修正: 個々のトリガーに固有のコンカレンシーに対してホスト レベルの制限を構成できます。 このモデルは、Functions の既定のコンカレンシー動作です。
- 動的コンカレンシー: 特定の種類のトリガーの場合、Functions ホストは、関数アプリでそのトリガーに最適なレベルのコンカレンシーを自動的に決定できます。 このコンカレンシー モデルにオプトインする必要があります。
この記事では、Functions でのイベント ドリブン トリガーのコンカレンシー動作と、これらの動作が動的プランのスケーリングにどのように影響するかを説明します。 また、固定インスタンスごとのコンカレンシー モデルと動的コンカレンシー モデルも比較します。
スケーリングとコンカレンシー
イベントベースのトリガーを使用する関数や HTTP 要求に応答する関数の場合は、需要の高い期間中に同時実行の制限にすばやく到達できます。 このような期間中は、受信要求の処理でバックログが発生しないようにインスタンスを追加することで、関数アプリをスケーリングできる必要があります。 アプリをスケーリングする方法は、ホスティング プランによって異なります。
| スケールの種類 | ホスティング プラン | 説明 |
|---|---|---|
| 動的 (イベント ドリブン) スケーリング |
消費 Flex Consumption プレミアム |
動的スケール プランでは、ホストは、受信イベントの数に基づいて関数アプリ インスタンスの数をスケールアップまたはスケールダウンします。 詳細については、「 Azure Functions でのイベントドリブン スケーリング」を参照してください。 |
| 手動スケーリング | 専用 (App Service) プラン | 専用プランで関数アプリをホストする場合は、負荷が高い期間中にインスタンスを手動で構成するか、 自動スケール スキームを設定する必要があります。 |
スケーリングが発生する前に、関数アプリは、1 つのインスタンスで同じ型の複数の呼び出しを処理することで、負荷の増加を処理しようとします。 その結果、特定のインスタンスでのこれらの同時実行は、スケールの決定に直接影響します。 たとえば、動的スケール プランのアプリがコンカレンシーの制限に達した場合、受信需要に対応するためにスケーリングが必要になる場合があります。
アプリで実現しようとするスケールとコンカレンシーのバランスは、ボトルネックが発生する可能性がある場所 (処理 (CPU 負荷の高いプロセス制限) またはダウンストリーム サービス (I/O ベースの制限) によって異なります。
インスタンスごとの同時実行を修正しました
既定では、ほとんどのトリガーでは、 ターゲット ベースのスケーリングを使用して、インスタンスごとの固定コンカレンシー構成モデルがサポートされます。 このモデルでは、トリガーの各種類に、インスタンスごとのコンカレンシー制限があります。
ほとんどのトリガーのコンカレンシーの既定値をオーバーライドするには、そのトリガーの種類に対して特定のインスタンスごとのコンカレンシーを設定します。 多くのトリガーでは、 host.json ファイルでコンカレンシー設定を構成します。 たとえば、 Azure Service Bus トリガー では、host.jsonで MaxConcurrentCalls と MaxConcurrentSessions の両方の設定が提供 されます 。 これらの設定は連携して、各関数アプリが各インスタンスで同時に処理するメッセージの最大数を制御します。
Apache Kafka トリガーや Azure Cosmos DB トリガーを使用する場合など、特定のターゲット ベースのスケーリング シナリオでは、コンカレンシー構成は 、host.json ファイルではなく関数宣言内にあります。 他のトリガーの種類には、インスタンス間で呼び出しを負荷分散するための組み込みメカニズムがあります。 たとえば、Azure Event Hubs と Azure Cosmos DB はどちらもパーティション ベースのスキームを使用します。
コンカレンシー構成をサポートするトリガーの種類の場合、コンカレンシー設定は実行中のすべてのインスタンスに適用されます。 これにより、各インスタンスの関数の最大コンカレンシーを制御できます。 たとえば、関数が CPU を集中的に使用する場合やリソースを集中的に使用する場合は、インスタンスを正常に保つためにコンカレンシーを制限することを選択できます。 この場合は、スケーリングに依存して負荷の増加を処理できます。 同様に、関数が制限されているダウンストリームサービスに対して要求を行う場合は、ダウンストリームサービスのオーバーロードを避けるために並行処理の制限も検討する必要があります。
HTTP トリガーのコンカレンシー
Flex 従量課金プランにのみ適用されます
HTTP トリガーコンカレンシーは、インスタンスごとの固定コンカレンシーの特殊な種類です。 HTTP トリガーコンカレンシーでは、既定のコンカレンシーも インスタンス サイズによって異なります。
Flex 従量課金プランでは、すべての HTTP トリガー関数がまとめてスケーリングされます。 詳細については、「関数ごとのスケーリング」を参照してください。
次の表は、構成されたインスタンスのメモリ サイズに基づいて、特定のインスタンスの HTTP トリガーの既定のコンカレンシー設定を示しています。
| インスタンスのサイズ (MB) | 既定のコンカレンシー* |
|---|---|
| 512 | 4 |
| 2,048 | 16 |
| 4,096 | 32 |
*Python アプリでは、すべてのインスタンス サイズで HTTP トリガーコンカレンシー レベル 1 が既定で使用されます。
これらの既定値はほとんどの場合に適しており、最初に使用できます。 任意の HTTP 要求数において、HTTP のコンカレンシー数を増やすことで、HTTP 要求の処理に必要なインスタンスの数は減少します。 同様に、HTTP コンカレンシー値を減らすには、同じ負荷を処理するために必要なインスタンスが増える必要があります。
HTTP コンカレンシーを微調整する必要がある場合は、Azure CLI を使用してこれを行うことができます。 詳細については、「HTTP コンカレンシーの制限を設定する」を参照してください。
前の表の既定のコンカレンシー値は、独自の HTTP コンカレンシー設定を設定していない場合にのみ適用されます。 HTTP コンカレンシー設定を明示的に設定しない場合、インスタンス サイズを変更すると、表に示すように既定のコンカレンシーが増加します。 特定の HTTP コンカレンシー値を設定すると、インスタンスのサイズを変更してもその値は維持されます。
インスタンスごとの最適な固定コンカレンシーを決定する
インスタンスごとのコンカレンシー構成を修正すると、関数の調整など、特定のトリガー動作を制御できます。 ただし、これらの設定に最適な値を特定することは困難な場合があります。 一般的には、ロード テストを反復して行うことで、許容できる値を導き出さなければなりません。 特定の読み込みプロファイルに対して機能する値のセットを決定した後でも、接続されたサービスから到着するイベントの数は日ごとに変わる可能性があります。 この変動により、アプリが最適でない値で実行される可能性があります。 たとえば、関数アプリでは、要求の厳しいメッセージ ペイロードを週の最後の日に処理する場合があり、コンカレンシーを調整する必要があります。 ただし、週の残りの期間は、メッセージペイロードが軽くなる可能性があります。つまり、週の残りの部分では、より高いコンカレンシー レベルを使用できます。
理想的には、システムはインスタンスができるだけ多くの作業を処理できるようにし、各インスタンスの正常性と待機時間を低く保つ必要があります。 動的コンカレンシーは、その目的のために設計されています。
動的な同時実行制御
Functions には、同じプランで実行されるすべての関数アプリのコンカレンシーの構成を簡略化する動的コンカレンシー モデルが用意されています。
Note
動的コンカレンシーは現在、Azure Blob Storage、Azure Queue Storage、Service Bus トリガーでのみサポートされています。 また、この記事で後述する拡張機能 のサポートに記載されている拡張機能のバージョンを使用する必要があります。
メリット
動的コンカレンシーには、次の利点があります。
- 構成の簡略化: トリガーごとの同時実行の設定を手動で決定する必要がなくなりました。 システムは、ワークロードに最適な値を時間をかけて学習します。
- 動的な調整: 同時実行はリアルタイムで動的に上下に調整されるため、システムは時間の経過と共に変化するロード パターンに対応することができます。
- インスタンスの正常性保護: ランタイムは、コンカレンシーを、関数アプリ インスタンスが快適に処理できるレベルに制限します。 これらの制限により、アプリが必要以上に多くの作業を引き受けることによって、アプリ自体が過負荷にならないように保護されます。
- スループットの向上: 個々のインスタンスが迅速に処理できるよりも多くの作業を引き出さないため、全体的なスループットが向上します。 その結果、作業はインスタンス間でより効果的に負荷分散されます。 高負荷を処理できる関数の場合は、既定の構成値以上にコンカレンシー数を増やすことで、スループットを高めることができます。
動的な同時実行制御の構成
host.json ファイルのホスト レベルで動的コンカレンシーを有効にすることができます。 オンにすると、この機能をサポートするすべてのバインディング拡張機能のコンカレンシー レベルが、必要に応じて自動的に調整されます。 こうした場合には、動的コンカレンシー設定が、手動で構成されたコンカレンシー設定をオーバーライドします。
既定では、動的コンカレンシーはオフになっています。 動的コンカレンシーを有効にすると、コンカレンシーは関数ごとに 1 レベルで開始されます。 コンカレンシー レベルは、ホストによって決定される最適な値に調整されます。
関数アプリで動的コンカレンシーを有効にするには、 host.json ファイルに次の設定を追加します。
{
"version": "2.0",
"concurrency": {
"dynamicConcurrencyEnabled": true,
"snapshotPersistenceEnabled": true
}
}
snapshotPersistenceEnabledがtrue (既定値) の場合、学習したコンカレンシー値は定期的にストレージに保持されます。 新しいインスタンスは、レベル 1 から開始して学習をやり直す必要があるのではなく、これらの値から開始されます。
同時実行マネージャー
バックグラウンドで動的コンカレンシーを有効にすると、コンカレンシー マネージャー プロセスがバックグラウンドで実行されます。 このマネージャーは、CPU とスレッドの使用率などのインスタンスの正常性メトリックを常に監視し、必要に応じてスロットルを変更します。 1 つまたは複数のスロットルがオンになっている場合、関数の同時実行数が、ホストが正常な状態になるまで減らされて調整されます。 スロットルをオフにすると、コンカレンシーが増加する可能性があります。 これらのスロットルに基づいて、必要に応じて様々なヒューリスティックを使用して同時実行数が上下に調整されます。 時間の経過と共に、各関数の同時実行数が特定のレベルに安定します。 最適なコンカレンシー値の決定には時間がかかる可能性があるため、動的コンカレンシーは、ソリューションに対して最適でない値が最初または一定の時間だけ許容される場合にのみ使用します。
同時実行のレベルは、個々の関数ごとに管理されます。 具体的には、低レベルのコンカレンシーを必要とするリソース集中型関数と、より高いコンカレンシーを処理できるより軽量な関数の間で、システムのバランスが取られます。 各関数のコンカレンシーのバランスは、関数アプリ インスタンスの全体的な正常性を維持するのに役立ちます。
動的コンカレンシーを有効にすると、ログに動的なコンカレンシーの決定が表示されます。 たとえば、さまざまなスロットルが有効になっている場合や、各関数のコンカレンシーが上下に調整されるたびに、ログ エントリが追加されます。 これらのログは、トレース テーブルの Host.Concurrency ログ カテゴリの下に書き込まれます。
拡張機能サポート
動的な同時実行制御は、ホスト レベルで関数アプリに対して有効化され、動的な同時実行制御をサポートするすべての拡張機能はそのモードで実行されます。 動的な同時実行制御を行うには、ホストと個々のトリガー拡張機能との連携が必要です。 動的な同時実行は、次の拡張機能の一覧にあるバージョンのみでサポートされています。
| 拡張機能 | Version | 説明 |
|---|---|---|
| キューストレージ | バージョン 5.x (ストレージ拡張機能) | Queue Storage トリガーには、独自のメッセージ ポーリング ループがあります。 固定インスタンスごとの構成を使用すると、 BatchSize と NewBatchThreshold の構成オプションによってコンカレンシーが制御されます。 動的コンカレンシーを使用する場合、これらの構成値は無視されます。 動的コンカレンシーはメッセージ ループに統合されるため、反復ごとに取得されるメッセージの数が動的に調整されます。 スロットルをオンにすると、ホストがオーバーロードされます。 メッセージ処理は、スロットルがオフになるまで一時停止されます。 スロットルがオフになると、同時実行性が増加します。 |
| Blob Storage | バージョン 5.x (ストレージ拡張機能) | 内部的には、Blob Storage トリガーは、Queue Storage トリガーが使用するのと同じインフラストラクチャを使用します。 新しい BLOB または更新された BLOB を処理する必要がある場合、メッセージはプラットフォームで管理される制御キューに書き込まれます。 そのキューは、キュー ストレージ トリガーに使用されるのと同じロジックを使用して処理されます。 動的コンカレンシーを有効にすると、その制御キューの処理のコンカレンシーが動的に管理されます。 |
| Service Bus | バージョン 5.x | 現在、Service Bus トリガーでは、3 つの実行モデルをサポートしています。 動的コンカレンシーは、次の方法でこれらの実行モデルに影響します。MaxConcurrentCalls 構成オプションによってコンカレンシーが制御されます。 動的コンカレンシーを使用すると、その構成値は無視され、コンカレンシーは動的に調整されます。MaxConcurrentSessions 設定によってコンカレンシーが制御されます。 動的コンカレンシーを有効にすると、 MaxConcurrentSessions 値は無視され、各インスタンスが処理するセッションの数が動的に調整されます。MaxMessageCount 設定によって制御されるメッセージのバッチを処理します。 バッチ呼び出しはシリアルであるため、バッチによってトリガーされる関数のコンカレンシーは常に 1 つであり、動的コンカレンシーは適用されません。 |
次のステップ
詳細については、次のリソースを参照してください。