Lambda 実行環境
Lambda は、実行環境で関数を呼び出します。これにより、安全で分離されたランタイム環境が提供されます。実行環境は、関数の実行に必要なリソースを管理します。また、関数のランタイム、および関数に関連付けられた外部拡張機能のライフサイクルサポートも提供します。
関数のランタイムは、ランタイム API を使用して Lambda と通信します。拡張機能は、拡張機能 API を使用して Lambda と通信します。拡張機能は、Telemetry API を使用することで、関数からログメッセージとその他のテレメトリを受け取ることもできます。

Lambda 関数を作成する際に、関数に許可するメモリ容量や最大実行時間など、設定情報を指定します。Lambda はこの情報を使用して実行環境をセットアップします。
関数のランタイムと各外部拡張機能は、実行環境内で実行されるプロセスです。アクセス許可、リソース、認証情報、および環境変数は、関数と拡張機能の間で共有されます。
Lambda 実行環境のライフサイクル

各フェーズは、ランタイムと、登録されているすべての拡張機能に Lambda を送信するイベントから始まります。ランタイムと各拡張機能は、Next
API リクエストを送信することで完了を示します。Lambda は、ランタイムと各拡張機能が完了して保留中のイベントがなくなると、実行環境をフリーズします。
初期化フェーズ
Init
フェーズでは、Lambda は次の 3 つのタスクを実行します。
-
すべての拡張機能を起動する (
Extension init
) -
ランタイムをブートストラップする (
Runtime init
) -
関数の静的コード (
Function init
) を実行する -
任意の
beforeCheckpoint
ランタイムフックを実行する (Lambda SnapStart のみ)
この Init
フェーズは、ランタイムとすべての拡張機能が Next
API リクエストを送信して準備完了を示したときに終了します。Init
フェーズは 10 秒に制限されています。3 つのタスクすべてが 10 秒以内に完了しない場合、Lambda は最初の関数呼び出し時に、設定された関数タイムアウトで Init
フェーズを再試行します。
Lambda SnapStart がアクティブ化されると、関数バージョンの発行時に Init
フェーズが開始されます。Lambda は、初期化された実行環境のメモリとディスク状態のスナップショットを保存し、暗号化されたスナップショットを永続化して、低レイテンシーアクセスのためにスナップショットをキャッシュします。beforeCheckpoint
ランタイムフックがある場合、コードは Init
フェーズの最後に実行されます。
注記
SnapStart 関数に 10 秒のタイムアウトは適用されません。Lambda がスナップショットを作成するときは、初期化コードが最大 15 分間実行される場合があります。制限時間は 130 秒、または設定されている関数のタイムアウト (最大 900 秒) のいずれか長い方です。
プロビジョニングされた同時実行を使用すると、Lambda は関数バージョンを発行した直後に init
フェーズを開始します。関数の初期化フェーズと呼び出しフェーズの間に大きなギャップが生じる可能性があります。予約されていない (オンデマンド) 同時実行を使用する関数の場合、Lambda は、呼び出しがない場合でも先を見越して関数インスタンスを初期化することがあります。これが発生すると、関数の初期化フェーズと呼び出しフェーズの間に予期しない時間のギャップが発生することがあります。このギャップは、プロビジョニングされた同時実行を使用するときに発生するものと同じように見える場合があります。
復元フェーズ (Lambda SnapStart のみ)
SnapStart 関数を初めて呼び出し、その関数がスケールアップすると、Lambda は関数をゼロから初期化するのではなく、永続化されたスナップショットから新しい実行環境を再開します。afterRestore()
ランタイムフックがある場合、コードは Restore
フェーズの最後に実行されます。ユーザーには、afterRestore()
ランタイムフックの所要時間分の料金が請求されます。タイムアウト制限 (10 秒) 内にランタイム (JVM) がロードされ、afterRestore()
ランタイムフックが完了される必要があります。その時間を超えると、SnapStartTimeoutException が発生します。Restore
フェーズが完了すると、Lambda が関数ハンドラーを呼び出します (Invoke
フェーズ)。
呼び出しフェーズ
Next
API リクエストに応答して Lambda 関数が呼び出されると、Lambda はランタイムと各拡張機能に Invoke
イベントを送信します。
関数のタイムアウト設定は、Invoke
フェーズ全体の所要時間を制限します。例えば、関数のタイムアウトを 360 秒に設定した場合、関数とすべての拡張機能は 360 秒以内に完了する必要があります。独立した呼び出し後フェーズはないことに注意してください。所要時間は、すべての呼び出し時間 (ランタイム + 拡張機能) の合計であり、関数とすべての拡張機能の実行が終了するまで計算されません。
呼び出しフェーズはランタイム後に終了し、すべての拡張機能は Next
API リクエストを送信して、完了したことを示します。
呼び出しフェーズ中の失敗
Lambda 関数が Invoke
フェーズ中にクラッシュするかタイムアウトすると、Lambda は実行環境をリセットします。次の図は、呼び出しに失敗した場合の Lambda 実行環境の動作を示しています。

前示の図では次のとおりです。
-
最初のフェーズは、エラーなしで実行される INIT フェーズです。
-
2 番目のフェーズは、エラーなしで実行される INVOKE フェーズです。
-
ある時点で、関数で呼び出しエラー (関数のタイムアウトやランタイムエラーなど) が発生したとします。INVOKE WITH ERROR というラベルの付いた 3 番目のフェーズは、このシナリオを示しています。これが発生すると、Lambda サービスはリセットを実行します。リセットは
Shutdown
イベントのように動作します。まず、Lambda はランタイムをシャットダウンし、登録された各外部拡張機能にShutdown
イベントを送信します。イベントには、シャットダウンの理由が含まれます。この環境が新しい呼び出しに使用される場合、Lambda は次の呼び出しとともに拡張機能とランタイムを再び初期化します。注記
Lambda のリセットでは、次の init フェーズより前の
/tmp
ディレクトリコンテンツはクリアされません。この動作は、通常のシャットダウンフェーズと一致しています。 -
4 番目のフェーズは、呼び出しが失敗した直後の INVOKE フェーズを表します。ここで、Lambda は INIT フェーズを再実行して環境を再び初期化します。これは、抑制された初期化と呼ばれます。抑制された初期化が発生した場合、Lambda は CloudWatch Logs で追加の INIT フェーズを明示的にレポートしません。代わりに、REPORT 行の期間に追加の INIT 期間 + INVOKE 期間が含まれる場合があります。例えば、CloudWatch で次のログが表示されたとします。
2022-12-20T01:00:00.000-08:00 START RequestId: XXX Version: $LATEST 2022-12-20T01:00:02.500-08:00 END RequestId: XXX 2022-12-20T01:00:02.500-08:00 REPORT RequestId: XXX Duration: 3022.91 ms Billed Duration: 3000 ms Memory Size: 512 MB Max Memory Used: 157 MB
この例では、REPORT タイムスタンプと START タイムスタンプの差は 2.5 秒です。これは、報告された 3022.91 ミリ秒の期間とは一致しません。なぜなら、Lambda が実行した追加の INIT (抑制された init) が考慮されていないからです。この例では、実際の INVOKE フェーズでは 2.5 秒かかったと推測できます。
この動作に関するより多くのインサイトを得るために、Lambda Telemetry API を使用できます。Telemetry API は、抑制された初期化が呼び出しフェーズの間で発生するたびに、
phase=invoke
のINIT_START
、INIT_RUNTIME_DONE
、およびINIT_REPORT
イベントを発行します。 -
5 番目のフェーズは、エラーなしで実行される SHUTDOWN フェーズを表します。
シャットダウンフェーズ
Lambda は、ランタイムをシャットダウンしようとする際、Shutdown
イベントを登録された各外部拡張機能に送信します。拡張機能は、この時間を最終的なクリーンアップタスクに使用できます。Shutdown
イベントは、Next
API リクエストに対するレスポンスです。
期間: Shutdown
フェーズ全体の上限は 2 秒です。ランタイムまたは拡張機能が応答しない場合、Lambda は通知 (SIGKILL
) によりそれを終了します。
関数とすべての拡張機能が完了した後、Lambda は別の関数の呼び出しを想定して、実行環境をしばらく維持します。実際には、Lambda は実行環境をフリーズします。関数が再び呼び出されると、再利用のため、Lambda によって環境が解凍されます。実行環境の再利用には、次のような意味があります。
-
関数ハンドラーメソッドの外部で宣言されたオブジェクトは、初期化されたままとなり、関数が再度呼び出されると追加の最適化を提供します。例えば、Lambda 関数がデータベース接続を確立する場合、連続した呼び出しでは接続を再確立する代わりに元の接続が使用されます。新しい接続を作成する前に、接続が存在するかどうかを確認するロジックをコードに追加することをお勧めします。
-
各実行環境は、
/tmp
ディレクトリに 512 MB と 10,240 MB 間を 1 MB 刻みで提供します。ディレクトリのコンテンツは、実行環境が停止された際に維持され、複数の呼び出しに使用できる一時的なキャッシュを提供します。キャッシュに保存したデータが存在するかどうかを確認するための追加コードを追加できます。デプロイのサイズ制限の詳細については、「Lambda クォータ」を参照してください。 -
Lambda 関数によって開始され、関数が終了したときに完了しなかったバックグラウンドプロセスまたはコールバックは、Lambda 関数が実行環境を再利用したときに再開します。コードのバックグラウンド処理またはコールバックは、コード終了までに完了させてください。
関数コードを記述するときは、Lambda が後続の関数呼び出しで実行環境を自動的に再利用するとは考えないでください。他の要因により、Lambda によって新しい実行環境が作成される場合があり、データベース接続の失敗など予期しない結果になることがあります。