Lambda 実行環境 - AWS Lambda

Lambda 実行環境

Lambda は、実行環境で関数を呼び出します。これにより、安全で分離されたランタイム環境が提供されます。実行環境は、関数の実行に必要なリソースを管理します。また、関数のランタイム、および関数に関連付けられた外部拡張機能のライフサイクルサポートも提供します。

関数のランタイムは、ランタイム API を使用して Lambda と通信します。拡張機能は、拡張機能 API を使用して Lambda と通信します。拡張機能は、Telemetry API を使用することで、関数からログメッセージとその他のテレメトリを受け取ることもできます。

実行環境のアーキテクチャ図。

Lambda 関数を作成する際に、関数に許可するメモリ容量や最大実行時間など、設定情報を指定します。Lambda はこの情報を使用して実行環境をセットアップします。

関数のランタイムと各外部拡張機能は、実行環境内で実行されるプロセスです。アクセス許可、リソース、認証情報、および環境変数は、関数と拡張機能の間で共有されます。

Lambda 実行環境のライフサイクル

Init フェーズの後に 1 つ以上の関数呼び出しが続きます。呼び出しリクエストがない場合、Lambda は Shutdown フェーズを開始します。

各フェーズは、ランタイムと、登録されているすべての拡張機能に 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 フェーズの最後に実行されます。

注記

10 秒のタイムアウトは、プロビジョニングされた同時実行または を使用している関数には適用されません SnapStart。プロビジョニングされた同時実行数と SnapStart 関数の場合、初期化コードは最大 15 分間実行できます。制限時間は 130 秒、または設定されている関数のタイムアウト (最大 900 秒) のいずれか長い方です。

プロビジョニング済み同時実行を使用する場合、関数の PC 設定を行う際、Lambda は実行環境を初期化します。また Lambda は、初期化された実行環境が呼び出し前に常に使用できるようにします。関数の呼び出しフェーズと初期化フェーズの間に予期しないギャップが発生する場合があります。関数のランタイムとメモリ設定によっては、初期化された実行環境での最初の呼び出しでレイテンシーの変動が発生する場合があります。

オンデマンド同時実行を使用する関数の場合、Lambda は呼び出しリクエストの前に実行環境を初期化することがあります。これが発生すると、関数の初期化フェーズと呼び出しフェーズの間に時間のギャップが発生することがあります。この動作に依存しないことをお勧めします。

初期化フェーズ中の失敗

Init フェーズ中に関数がクラッシュするかタイムアウトすると、Lambda は INIT_REPORT ログにエラー情報を出力します。

例 — タイムアウトの INIT_REPORT ログ
INIT_REPORT Init Duration: 1236.04 ms Phase: init Status: timeout
例 — 拡張が失敗したときの INIT_REPORT ログ
INIT_REPORT Init Duration: 1236.04 ms Phase: init Status: error Error Type: Extension.Crash

Init フェーズが成功した場合、Lambda はINIT_REPORTログを出力しません。ただし、 SnapStartがアクティブになっている場合を除きます。 SnapStart 関数は常に を出力しますINIT_REPORT。詳細については、「Lambda のモニタリング SnapStart」を参照してください。

復元フェーズ (Lambda SnapStart のみ)

最初にSnapStart関数を呼び出し、関数がスケールアップすると、Lambda は関数を最初から初期化するのではなく、永続化されたスナップショットから新しい実行環境を再開します。afterRestore() ランタイムフックがある場合、コードは Restore フェーズの最後に実行されます。ユーザーには、afterRestore() ランタイムフックの所要時間分の料金が請求されます。タイムアウト制限 (10 秒) 内にランタイム (JVM) がロードされ、afterRestore() ランタイムフックが完了される必要があります。それ以外の場合は、 を取得します SnapStartTimeoutException。Restore フェーズが完了すると、Lambda が関数ハンドラーを呼び出します (呼び出しフェーズ)。

復元フェーズ中の失敗

Restore フェーズが失敗した場合、Lambda は RESTORE_REPORT ログにエラー情報を出力します。

例 — タイムアウトの RESTORE_REPORT ログ
RESTORE_REPORT Restore Duration: 1236.04 ms Status: timeout
例 — ランタイムフック障害の RESTORE_REPORT ログ
RESTORE_REPORT Restore Duration: 1236.04 ms Status: error Error Type: Runtime.ExitError

RESTORE_REPORT ログの詳細については、「Lambda のモニタリング SnapStart」を参照してください。

呼び出しフェーズ

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 ログに追加の 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=invokeINIT_STARTINIT_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 によって新しい実行環境が作成される場合があり、データベース接続の失敗など予期しない結果になることがあります。