Lambdaの実行環境について(コールドスタートとウォームスタート)
はじめに
- 昨年、awsブログにてOperating Lambdaシリーズの翻訳版が公開された。
- Lambdaを使う開発者にとっては知っておくべきことが詰まったこのブログ、3本から構成されています。今回はその内容から一部抜粋してLambdaのコールドスタートとウォームスタートについて取り上げまとめてみましたという記事です。
コールドスタートとレイテンシー、そしてウォームスタート
下記の図は、Lambdaの関数実行のrequestを受け取ってから、ハンドラ関数実行までの流れを表しています。
Lambdaは、Lambda APIを介して関数実行された時次のような動作をします。
1: S3バケットから実行するコードのダウンロードを行ったり、コンテナパッケージを使用している場合はECRよりダウンロードします。
2: 指定されたメモリ、ランタイム及び各種設定に基づいた環境を作成します。
3: Lambdaのハンドラ関数外の初期化コードを実行します。
4: Lambdaのハンドラ関数の実行
- Lambdaにおけるコールドスタートはこのコード準備と環境準備のステップです。
- lambdaがコールドスタートするのは有名だと思いますし、課金対象もこのコールドスタートで起きる最初の環境準備は含まれません。
実は、lambdaは必ずしもコールドスタートで始まるわけではありません。
- Lambdaの実行が完了した後、Lambdaは実行環境を不特定期間保持します。
- その為、この時同じ関数にリクエストがあった場合、Lambdaは環境の再利用を行うのです。
これは、これはコールドスタートとは異なり、コールドスタートされていたステップ(コード準備と環境作成)が省略されるので、ウォームスタートとなります。
実行環境のライフサイクル
- Lambdaは、関数実行後、その環境をすぐ破棄することなく保持します。
- ただ、この環境破棄までの期間を指定することはできません。
- またLambdaのウォームスタートをパフォーマンスの最適化とし、ウォームスタート依存するのはよくありません。
=> なぜならば、LambdaがAZに跨って実行を管理するサービスだからです。
その為、実行されたLambdaがその後ウォームスタートすると思いきや、コールドスタートになるという可能性も考えられます。
=> さらに、Lambdaがスケールアップされる際に関数の追加が発生したとします。そうすると、その場合においても新たな実行環境の作成が行われるので、追加分の関数についてはコールドスタートになります。
=> また、コードの更新や、関数の設定変更等を行い新しいバージョンのコードのみが使用されるようエイリアス設定されている場合は、実行している既存の環境は破棄されます。この場合もコールドスタートになります。
Lambdaを定常でウォームスタートされるために方法(EventBridgeを使い1分ごとに関数の呼び出しをpingで行う方法)もあるようだが、公式ブログ内ではこの方法だとコールドスタートを減らす保証がないことが記載されています。
パフォーマンスの最適化
Lambdaにおける機能にProvisioned Concurrencyがあります。これを使用すると、コールドスタートの削減につながります。
Provisioned Concurrencyの機能とは、事前に同時実行環境を準備しておく機能です。
準備される範囲としては、コードの準備、環境の作成、ハンドラ外の初期化コードの実行までを事前に構築実行しておきます。
これにより解決する課題は、2つで、初期リクエストに関して完全にコールドスタートとなりレイテンシーが大きくなる課題と、スパイクなリクエストが来た時にスケーリングが追いつかない課題です。
まあ、その分料金がProvisioned Concurrency料金 + リクエスト料金 + コンピューティング料金となるので、そこが注意点です。
引用元
Discussion