Lambda利用時によく話題になるコールドスタート問題についてメモする。
Lambda実行の流れとコールドスタート
Lambda サービスが関数を実行するリクエストを受け取り、以下を実行する。
- サービスは内部の Amazon S3バケット (関数がコンテナパッケージを使用する場合はAmazon ECR) に保存されている関数コードをダウンロードする。
- 指定されたメモリ、ランタイム、各種設定に基づいた環境を作成する。
- Lambda はイベントハンドラー外に記述された初期化コードを実行する。
- ハンドラーコードを実行する。
上記1,2のステップを実行することを「コールドスタート」と呼ぶ。
このコールドスタートステップに要する時間は課金されないが、全体的な実行時間に対して遅延を及ぼす。
- コールドスタートに要する時間は、100 ミリ秒未満から 1 秒以上まで様々...
- 実行が完了すると、リソース管理とパフォーマンスを向上させるために、Lambdaは実行環境を不特定期間保持する。
- この間、同じ関数に対する追加のリクエストが到着すると、サービスは環境を再利用するよう試みる。
- この 2 番目のリクエストは実行環境がすでに存在し、コードをダウンロードして初期化コードを実行する必要がないため迅速に終了する。
- これは「ウォームスタート」と呼ぶ。
実行環境のライフサイクル
-
Lambdaは、実行後すぐには実行環境を破棄せず、保持し続ける。
- 環境の保持期間は様々な要因の影響を受け、開発者が設定することはできない。
-
実行環境の再利用は有用だが、下記理由からパフォーマンスの最適化をこれに依存すべきではない。
-
Lambda は、AWS リージョン内の複数の AZに跨って実行管理されるため、リクエスト量に応じて関数をロードバランスする可能性がある。その結果、短時間に関数が 2 回呼び出されたとしても、いずれの実行においてもコールドスタートが発生する事態も起こり得る。
-
リクエストによってLambda 関数がスケールアップされる際には、関数の追加の同時呼び出しごとに新たな実行環境が必要となる。
- すでにウォーム状態になっている既存の同時実行可能な関数が存在する場合も、追加の同時実行分においてはコールドスタートが発生する。
-
Lambda 関数のコードを更新したり、関数の設定を変更した場合、次の呼び出しでコールドスタートが発生する。
-
対策1:Provisioned Concurrency
- 事前に同時実行環境(コードダウンロード、環境作成、初期化コードの実行)を整える機能。
- 関数は初期化およびウォームアップされ、プロビジョニングしたスケールで 2 桁のミリ秒で応答できる準備が整う。
※Provisioned Concurrency 料金が別途発生する
- 関数は初期化およびウォームアップされ、プロビジョニングしたスケールで 2 桁のミリ秒で応答できる準備が整う。
対策2:Lambda SnapStart
- Lambda実行直前に環境のスナップショットを取得し、多層キャッシュに保存することで、それ以後のコンテナ初期化を高速化する機能。
- スナップショットには初期化後、実行開始直前の関数のメモリとディスクの状態が記録される。