Lambda 関数の同時実行数の管理 - AWS Lambda

Lambda 関数の同時実行数の管理

同時実行数とは、ある時点で関数が処理しているリクエストの数を指します。関数が呼び出されると、Lambda はその関数のインスタンスを割り当ててイベントを処理します。関数コードの実行が完了すると、別のリクエストを処理できます。リクエストの処理中に関数が再度呼び出されると、別のインスタンスが割り当てられるため、関数の同時実行数が増えます。同時実行数は、リージョン内のすべての関数で共有されるリージョンのクォータの影響を受けます。

ご利用いただける同時実行コントロールには、次の 2 種類があります。

  • リザーブド同時実行 – リザーブド同時実行は、関数の同時インスタンスの最大数を保証します。ある関数が予約された同時実行数を使用している場合、他の関数はその同時実行数を使用できません。関数に対して予約された同時実行を設定する場合には料金はかかりません。

  • プロビジョニングされた同時実行 – プロビジョニングされた同時実行は、リクエストされた数だけの実行環境を初期化して、関数の呼び出しに即座に応答する準備を行います。プロビジョニングされた同時実行を設定すると、AWS アカウントに課金が発生することに注意してください。

このトピックでは、予約およびプロビジョニングされた同時実行を管理および設定する方法について説明します。同時実行がスケーリングとどのように相互作用するかについては、「Lambda 関数スケーリング」を参照してください。

関数の同時実行数を常に一定レベルにするには、その関数に予約された同時実行数を設定します。ある関数が予約された同時実行数を使用している場合、他の関数はその同時実行数を使用できません。予約された同時実行数は、関数の最大同時実行数も制限し、関数全体 (バージョンとエイリアスを含む) に適用されます。

Lambda が関数のインスタンスを割り当てると、ランタイムは関数のコードをロードし、ハンドラーの外部で定義された初期化コードを実行します。コードと依存関係が大きい場合、または初期化中に SDK クライアントを作成する場合、このプロセスには時間がかかることがあります。関数がスケールアップすると、これにより、新しいインスタンスによって処理されるリクエストの部分は、残りの部分よりも、レイテンシーが長くなります。

レイテンシーの変動なしに関数をスケーリングできるようにするには、プロビジョニングされた同時実行数を使用します。呼び出しの増加前にプロビジョニングされた同時実行数を割り当てることにより、すべてのリクエストが、非常に短いレイテンシーで、初期化されたインスタンスによって処理されるようにできます。プロビジョニングされた同時実行数は関数のバージョンまたはエイリアスに割り当てることができます。

Lambda は Application Auto Scaling とも統合されます。スケジュールに従って、または使用率に基づいて、プロビジョニングされた同時実行数を管理するように Application Auto Scaling を設定できます。スケジュールされたスケーリングを使用し、ピークトラフィックを見越して、プロビジョニングされた同時実行数を増やします。必要に応じてプロビジョニング済み同時実行数を自動的に増やすには、Application Auto ScalingAPI を使用してターゲットを登録し、スケーリングポリシーを作成します。

プロビジョニングされた同時実行数は、関数の予約された同時実行数とリージョンのクォータにカウントされます。関数のバージョンとエイリアスに割り当てたプロビジョニングされた同時実行数が、関数の予約された同時実行数に達すると、すべての呼び出しはプロビジョニングされた同時実行数を使用して実行されます。この設定には、非公開バージョンの関数 ($LATEST) をスロットリングする効果もあるため、その関数は実行されません。

注記

関数に対し、予約された同時実行数よりも多くのプロビジョニングされた同時実行を割り当てることはできません。

予約された同時実行数の設定

関数の予約された同時実行数の設定を管理するには、Lambda コンソールを使用します。

関数の同時実行数を予約するには

  1. Lambda コンソールの [Functions (関数)] ページを開きます。

  2. 関数を選択します。

  3. [設定]、[同時実行] の順にクリックします。

  4. [同時実行数] で、[編集] をクリックします。

  5. [同時実行の予約] をクリックします。関数用に予約する同時実行の量を入力します。

  6. [Save] を選択します。

表示されている [Unreserved account concurrency (予約されていないアカウントの同時実行数)] 値まで予約できます。予約された同時実行数のない関数の場合は、それより 100 少ない値まで予約できます。関数をスロットリングするには、予約された同時実行数をゼロに設定します。これにより、制限を削除するまで、イベントの処理が停止します。

次の例は、予約済み同時実行のプールを使用する 2 つの関数と、予約されていない同時実行のプールを使用する他の関数を示しています。スロットリングエラーは、プール内のすべての同時実行が使用されている場合に発生します。


        2 つの関数に割り当てられた予約済み同時実行数。

凡例

  • 関数の同時実行

  • 予約済み同時実行

  • 予約されていない同時実行

  • スロットリング

同時実行数をリザーブすると、次のことが起こります。

  • 他の関数が関数のスケーリングを防げなくなる – 予約された同時実行数のない同じリージョン内のアカウントの関数はすべて、予約されていない同時実行数のプールを共有します。予約された同時実行数がない場合、使用可能なすべての同時実行数を他の関数が使い果たす可能性があります。これにより、必要なときに関数がスケールアップしなくなります。

  • 関数のスケーリングが制御不能にならない – 予約された同時実行数は、関数が予約されていないプールの同時実行数を使用するのも制限するため、その関数の最大同時実行数に上限が設けられます。同時実行数を予約することで、リージョンで利用可能なすべての同時実行数を関数が使用したり、ダウンストリームリソースを過負荷にしたりしないようにできます。

関数あたりの同時実行数を設定すると、他の関数で使用できる同時実行数のプールに影響を与えることがあります。問題を回避するには、PutFunctionConcurrency および DeleteFunctionConcurrency API オペレーションを使用できるユーザーの数を制限します。

プロビジョニングされた同時実行数の設定

バージョンまたはエイリアスのプロビジョニングされた同時実行数の設定を管理するには、Lambda コンソールを使用します。

エイリアスの同時実行をプロビジョニングするには、

  1. Lambda コンソールの [Functions (関数)] ページを開きます。

  2. 関数を選択します。

  3. [設定]、[同時実行] の順にクリックします。

  4. [プロビジョニングされた同時実行設定] で、[追加] をクリックします。

  5. エイリアスまたはバージョンを選択します。

  6. 割り当てるプロビジョニングされた同時実行数を入力します。

  7. [Save] を選択します。

関数の設定ページから、すべてのエイリアスとバージョンのプロビジョニングされた同時実行数を管理できます。プロビジョニングされた同時実行数の設定のリストには、各設定の割り当ての進捗状況が表示されます。プロビジョニングされた同時実行数の設定は、各バージョンおよびエイリアスの設定ページでも利用できます。

次の例で、my-function-DEV 関数と my-function-PROD 関数には、予約済み同時実行とプロビジョニング済み同時実行の両方が設定されています。my-function-DEV の場合、予約済み同時実行のプール全体がプロビジョニング済み同時実行でもあります。この場合、すべての呼び出しは、プロビジョニング済み同時実行で実行されるか、スロットリングされます。my-function-PROD の場合、予約済み同時実行プールの一部が標準の同時実行です。すべてのプロビジョニング済み同時実行が使用されている場合、関数は追加のリクエストを処理するために標準の同時実行数をスケールします。


        同時実行数のリザーブとプロビジョニングされた同時実行数を持つ関数。

凡例

  • 関数の同時実行

  • 予約済み同時実行

  • プロビジョニング済み同時実行

  • 予約されていない同時実行

  • スロットリング

プロビジョニングされた同時実行数は、設定後すぐにはオンラインになりません。Lambda は、1~2 分の準備後に、プロビジョニングされた同時実行数の割り当てを開始します。関数の負荷時のスケーリング方法と同様に、リージョンに応じて、関数の最大 3000 インスタンスを一度に初期化できます。最初のバーストの後、リクエストが受理されるまで、インスタンスは 1 分あたり 500 という一定のレートで割り当てられます。同じリージョン内の複数の関数または関数のバージョンに対してプロビジョニングされた同時実行数をリクエストするとき、スケーリングクォータはすべてのリクエストに適用されます。


      プロビジョニングされた同時実行数によるスケーリング。

凡例

  • 関数のインスタンス数

  • 未処理のリクエスト数

  • プロビジョニング済み同時実行

  • 標準同時実行

プロビジョニングされた同時実行が使用される関数で、その初期化動作をカスタマイズすることで、レイテンシーを最適化できます。初期化コードは割り当てが行われる際に実行されます。したがって、このコードをプロビジョニングされた同時実行インスタンスで実行しても、レイテンシーには影響を与えません。ただし、オンデマンドインスタンスでは、その最初の呼び出しの際に、初期化コードがレイテンシーに直接的な影響を与えます。オンデマンドインスタンスの場合には、特定の機能のための初期化処理を、関数がその機能を必要とするまで延期することができます。

初期化のタイプを調べるには、環境変数 AWS_LAMBDA_INITIALIZATION_TYPE の値をチェックします。この値は Lambda により、provisioned-concurrency または on-demand に設定されています。AWS_LAMBDA_INITIALIZATION_TYPE の値は不変であり、実行環境のライフタイムにわたって変更されません。

.NET 3.1 ランタイムをご使用の場合には、環境変数 AWS_LAMBDA_DOTNET_PREJIT の設定により、プロビジョニングされた同時実行を使用する関数の、レイテンシーを向上させることができます。.NET ランタイムでは、コードが使用する各ライブラリのコンパイルと初期化が、そのライブラリに対する最初の呼び出しまで延期されます。その結果、Lambda 関数に対する最初の呼び出しが、その後の呼び出しよりも時間を要することがあります。AWS_LAMBDA_DOTNET_PREJIT を ProvisionedConcurrency に設定した場合、システムの一般的な依存関係のための JIT コンパイルが、前もって Lambda により実行されます。Lambda は、プロビジョニングされた同時実行インスタンスに対してのみ、この初期化処理の最適化を実行します。これにより、最初の呼び出し時のパフォーマンスが高速化されます。この環境変数を Always に設定した場合、Lambda は初期化のたびに JIT コンパイルを実行します。この環境変数を Never に設定した場合には、事前の JIT コンパイルは無効になります。AWS_LAMBDA_DOTNET_PREJIT のデフォルト値は ProvisionedConcurrency です。

プロビジョニングされた同時実行をご使用の場合、関数の実行インスタンスがリサイクルされるため、関数の初期化コードは、割り当て時とその後の数時間ごとに実行されるようになります。インスタンスでリクエストが処理された後、ログとトレースで初期化時間を確認できます。ただし、インスタンスでリクエストが処理されない場合でも、初期化の料金は発生します。関数はプロビジョニングされた同時実行数で継続的に実行され、初期化および呼び出しのコストとは別に料金が発生します。詳細については、「AWS Lambda 料金表」を参照してください。

関数の各バージョンには、プロビジョニングされた同時実行数の設定を 1 つのみ割り当てることができます。この設定は、バージョン自体に直接割り当てることも、バージョンを参照するエイリアスに割り当てることもできます。2 つのエイリアスに、同じバージョンのプロビジョニングされた同時実行数を割り当てることはできません。また、非公開バージョン ($LATEST) を参照するエイリアスにプロビジョニングされた同時実行数を割り当てることもできません。

エイリアスが参照するバージョンを変更すると、プロビジョニングされた同時実行数が古いバージョンから割り当て解除され、新しいバージョンに割り当てられます。プロビジョニングされた同時実行数を割り当てたエイリアスにルーティング設定を追加できます。ただし、ルーティング設定が有効になっている間は、エイリアスのプロビジョニングされた同時実行設定を管理できません。

Lambda から、プロビジョニングされた同時実行数について以下のメトリクスが出力されます。

プロビジョニングされた同時実行数のメトリクス

  • ProvisionedConcurrentExecutions

  • ProvisionedConcurrencyInvocations

  • ProvisionedConcurrencySpilloverInvocations

  • ProvisionedConcurrencyUtilization

詳細については、「AWS Lambda 関数メトリクスの使用」を参照してください。

Lambda API の使用による同時実行の設定

AWS CLI または AWS SDK で同時実行の設定と自動スケーリングを管理するには、以下の API オペレーションを使用します。

予約された同時実行数を AWS CLI で設定するには、put-function-concurrency コマンドを使用します。以下のコマンドは、my-function という名前の関数に 100 の同時実行数を予約します。

aws lambda put-function-concurrency --function-name my-function --reserved-concurrent-executions 100

次のような出力が表示されます。

{ "ReservedConcurrentExecutions": 100 }

プロビジョニングされた同時実行数を関数に割り当てるには、put-provisioned-concurrency-config を使用します。以下のコマンドは、my-function という名前の関数の BLUE エイリアスに 100 の同時実行数を割り当てます。

aws lambda put-provisioned-concurrency-config --function-name my-function \ --qualifier BLUE --provisioned-concurrent-executions 100

次のような出力が表示されます。

{ "Requested ProvisionedConcurrentExecutions": 100, "Allocated ProvisionedConcurrentExecutions": 0, "Status": "IN_PROGRESS", "LastModified": "2019-11-21T19:32:12+0000" }

プロビジョニング済み同時実行を管理するように Application Auto Scaling を設定するには、Application Auto Scaling を使用してターゲット追跡スケーリングを設定します。まず、関数のエイリアスをスケーリングターゲットとして登録します。次の例では、my-function という名前の関数の BLUE エイリアスを登録します。

aws application-autoscaling register-scalable-target --service-namespace lambda \ --resource-id function:my-function:BLUE --min-capacity 1 --max-capacity 100 \ --scalable-dimension lambda:function:ProvisionedConcurrency

次に、スケーリングポリシーをターゲットに適用します。次の例では、エイリアスのプロビジョニング済み同時実行の設定を調整して使用率が常に 70% 近くになるように Application Auto Scaling を設定します。

aws application-autoscaling put-scaling-policy --service-namespace lambda \ --scalable-dimension lambda:function:ProvisionedConcurrency --resource-id function:my-function:BLUE \ --policy-name my-policy --policy-type TargetTrackingScaling \ --target-tracking-scaling-policy-configuration '{ "TargetValue": 0.7, "PredefinedMetricSpecification": { "PredefinedMetricType": "LambdaProvisionedConcurrencyUtilization" }}'

次のような出力が表示されます。

{ "PolicyARN": "arn:aws:autoscaling:us-east-2:123456789012:scalingPolicy:12266dbb-1524-xmpl-a64e-9a0a34b996fa:resource/lambda/function:my-function:BLUE:policyName/my-policy", "Alarms": [ { "AlarmName": "TargetTracking-function:my-function:BLUE-AlarmHigh-aed0e274-xmpl-40fe-8cba-2e78f000c0a7", "AlarmARN": "arn:aws:cloudwatch:us-east-2:123456789012:alarm:TargetTracking-function:my-function:BLUE-AlarmHigh-aed0e274-xmpl-40fe-8cba-2e78f000c0a7" }, { "AlarmName": "TargetTracking-function:my-function:BLUE-AlarmLow-7e1a928e-xmpl-4d2b-8c01-782321bc6f66", "AlarmARN": "arn:aws:cloudwatch:us-east-2:123456789012:alarm:TargetTracking-function:my-function:BLUE-AlarmLow-7e1a928e-xmpl-4d2b-8c01-782321bc6f66" } ] }

Application Auto Scaling は CloudWatch に 2 つのアラームを作成します。最初のアラームは、プロビジョニング済み同時実行の使用率が一貫して 70% を超えたときにトリガーされます。この場合、Application Auto Scaling はプロビジョニング済み同時実行の割り当て数を増やして、使用率を下げます。2 番目のアラームは、使用率が一貫して 63% (70% ターゲットの 90%) を下回った場合にトリガーされます。この場合、Application Auto Scaling はエイリアスのプロビジョニング済み同時実行の割り当て数を減らします。

次の例では、使用状況に基づいてプロビジョニング済み同時実行の最小および最大量の間で関数がスケールします。未処理のリクエスト数が増える場合、Application Auto Scaling では、設定した最大数に達するまでプロビジョニング済みの同時実行を大きい幅で増やします。この関数では、使用量が下がり始めるまで標準の同時実行でスケールし続けます。使用量が一貫して低い場合、Application Auto Scaling では小刻みの定期的な幅でプロビジョニング済みの同時実行を減らします。


      Application Auto Scaling のターゲットの追跡でのプロビジョニング済み同時実行数の自動スケーリング。

凡例

  • 関数のインスタンス数

  • 未処理のリクエスト数

  • プロビジョニング済み同時実行

  • 標準同時実行

リージョンのアカウントの同時実行数クォータを表示するには、get-account-settings を使用します。

aws lambda get-account-settings

次のような出力が表示されます。

{ "AccountLimit": { "TotalCodeSize": 80530636800, "CodeSizeUnzipped": 262144000, "CodeSizeZipped": 52428800, "ConcurrentExecutions": 1000, "UnreservedConcurrentExecutions": 900 }, "AccountUsage": { "TotalCodeSize": 174913095, "FunctionCount": 52 } }