Lambda マネージドインスタンスの実行環境について理解する
Lambda マネージドインスタンスでは、Lambda が運用面を管理している間に、ユーザー所有の Amazon EC2 インスタンスで関数コードを実行する代替デプロイモデルを利用できます。マネージドインスタンスの実行環境には、Lambda (デフォルト) 関数との重要な違いがいくつかあります。特に違うのは、同時呼び出しの処理方法とコンテナライフサイクルの管理方法です。
注: Lambda (デフォルト) 実行環境の詳細については、「Lambda 実行環境のライフサイクルの概要」を参照してください。
実行環境のライフサイクル
Lambda マネージドインスタンス関数の実行環境のライフサイクルは、Lambda (デフォルト) とは異なる主要な点がいくつかあります。
初期化フェーズ
初期化フェーズでは、Lambda は次のステップを実行します。
-
すべての拡張機能を初期化して登録する
-
ランタイムエントリポイントをブートストラップする。ランタイムは、設定された数のランタイムワーカーを生成します (実装はランタイムによって異なります)
-
関数の初期化コードを実行する (ハンドラー外のコード)
-
/runtime/invocation/nextを呼び出して、1 つ以上のランタイムワーカーが準備状況を通知するまで待機する
拡張機能が初期化され、少なくとも 1 つのランタイムワーカーが /runtime/invocation/next を呼び出すと、初期化フェーズは完了したと見なされます。その後、関数の呼び出しを処理する準備が整います。
注記
Lambda マネージドインスタンス関数の場合、初期化には最大 15 分かかることがあります。制限時間は 130 秒、または設定されている関数のタイムアウト (最大 900 秒) のいずれかです。
呼び出しフェーズ
Lambda マネージドインスタンス関数の呼び出しフェーズには、固有の特性がいくつかあります。
オペレーションの継続。Lambda (デフォルト) とは異なり、実行環境は継続的にアクティブのままで、呼び出し間でフリーズすることなく到着時に呼び出しを処理します。
並列処理。同じ実行環境内で複数の呼び出しを同時に実行でき、それぞれ異なるランタイムワーカーによって処理されます。
タイムアウトの独立。関数で設定されたタイムアウトは、それぞれの呼び出しに適用されます。呼び出しがタイムアウトすると、Lambda はその特定の呼び出しを失敗としてマークしますが、実行中の他の呼び出しを中断したり、実行環境を終了したりしません。
バックプレッシャー処理。すべてのランタイムワーカーが呼び出しの処理中である場合、ワーカーが利用可能になるまで新しい呼び出しリクエストは拒否されます。
エラー処理と復旧
Lambda マネージドインスタンス関数の実行環境でのエラー処理は、Lambda (デフォルト) とは異なります。
ランタイムワーカーのエラー。ランタイムワーカーのプロセスがクラッシュした場合、実行環境は残りの正常なワーカーで動作し続けます。
拡張機能のクラッシュ。初期化またはオペレーション中に拡張機能プロセスがクラッシュすると、実行環境全体が異常としてマークされ、終了します。Lambda は、新しい実行環境を作成して置き換えます。
リセット/修復なし。Lambda (デフォルト) とは異なり、マネージドインスタンスではエラー後に実行環境のリセットと再初期化は試行されません。その代わり異常なコンテナは終了され、新しいコンテナに置き換えられます。
タイムアウトの呼び出し
個々の呼び出しがタイムアウトすると、Lambda は関数エラーのステータスを使用して Task timed out after <timeout> seconds エラーを呼び出し元に返します。ただし、Lambda マネージドインスタンスはコードを強制的に終了しません。実行環境で実行し続けます。関数の開発者は、タイムアウトの検出と処理を適切に実装する必要があります。コンテキストオブジェクトは、呼び出しの残り時間を公開します。ゼロまたは負の値は、呼び出しがタイムアウトしたことを示します。実行環境での他の同時呼び出しは、正常に処理を続行します。
再試行動作
呼び出しがタイムアウトした場合:
-
同期呼び出し: 呼び出し元がタイムアウトエラーを受け取り、再試行が必要となります。
-
非同期呼び出し: Lambda は関数の再試行ポリシーに基づいて再試行します (デフォルト: 再試行 2 回)。すべての再試行が終了すると、イベントは設定されたデッドレターキューまたは障害発生時の送信先 (存在する場合) に送信されます。
-
イベントソースマッピング: 再試行動作は、イベントソース設定 (バッチサイズ、エラー時の二等分、最大再試行回数など) によって異なります。バッチは、再試行ポリシーに基づいて再試行されるか、障害発生時の送信先に送信される場合があります。
タイムアウトを処理しない場合に起きること
コードが残り時間を確認せず、実行を停止した場合:
-
呼び出しは既に失敗とマークされている。Lambda は、既に呼び出し元にタイムアウトエラーを返しています。タイムアウト後にコードが完了した作業は、呼び出し元の観点から事実上失われます。
-
リソースは消費されたままである。コードは引き続きランタイムワーカースロットを占有し、そのインスタンスでの新しい呼び出しで使用できる同時実行数を減らします。
-
非決定的な動作。タイムアウトが発生してもコードは停止せず、バックグラウンドで実行され続けます。つまり、Lambda が呼び出しに失敗したことを呼び出し元に既に通知した後でも、副作用が発生する可能性があります。例えば、ハンドラーは DynamoDB にレコードを書き込み、タイムアウトが発生し、Lambda は呼び出し元にタイムアウトエラーを返しますが、コードはまだ実行されており、SNS 通知の送信に進みます。呼び出し元は呼び出しを再試行し、レコードを再度書き込み、通知を再送信します。これで、重複したデータと重複した通知が作成され、バックグラウンドでまだ実行されていた「失敗」の呼び出しから発生した通知がどれかを簡単に判断できなくなりました。
コード内のタイムアウトの処理
コンテキストオブジェクトを使用して残り時間を確認し、タイムアウト前に処理を停止します。次の作業単位の予想期間に基づいてバッファを設定します。例えば、各項目の処理に約 500 ミリ秒かかる場合は、少なくとも 500 ミリ秒にマージンを加えた値にバッファを設定します。
タイムアウト処理の言語固有の例については、各ランタイムページのリクエストコンテキストセクションを参照してください。