はじめに

AWS Lambda のコールドスタートとは Lambda 関数が呼び出されたときに Lambda サービスが新しい実行環境を初期化することです [1] 。 これが発生すると呼び出しへの応答に時間がかかり、例えばシステムの画面表示が遅くなるなどします。コールドスタートは Lambda を使う上でぜひ理解しておきたい挙動です。

本記事では AWS Lambda がどんなサービスか、コールドスタートとは何か、どう対策すべきかを説明しています。初学者の方を中心に活用していただけたら幸いです。

AWS Lambda とは

まずは AWS Lambda の概要を確認しましょう。AWS による説明を引用します。多くの用語が飛び交っていますが、ひとつずつ確認していきましょう。

AWS Lambda は、サーバーレスでイベント駆動型のコンピューティングサービスであり、サーバーのプロビジョニングや管理をすることなく、事実上あらゆるタイプのアプリケーションやバックエンドサービスのコードを実行することができます。200 以上の AWS のサービスやサービス型ソフトウェア (SaaS) アプリケーションから Lambda をトリガーすることができ、使用した分だけお支払いいただきます。
引用: AWS Lambda(イベント発生時にコードを実行)| AWS

コンピューティングサービスとはクラウド上でプログラムを実行するためのサービスです [3] 。AWS Lambda もそのひとつで、開発したウェブアプリを公開したり、大量の計算を行うプログラムを実行させたりできます。

AWS Lambda のコンソールでコードを実行する様子AWS Lambda のコンソールを使うと書いたコードをすぐ実行できる。

AWS Lambda は代表的な AWS のサーバレスサービスです。プログラムを実行している実際のサーバを意識せずに利用できるサービスをサーバレスといいます [4] 。サーバレスでないコンピューティングサービスの AWS EC2 では、サーバの台数・スペック・OS やミドルウェアなどを管理運用する労力がかかります。一方、Lambda ではそういった労力は最小限で済みます。Lambda にアップロードするだけでプログラムを実行でき、サーバの管理運用は AWS にお任せできます。

イベント発生をきっかけとして短い時間だけ・その都度プログラムが実行されるので AWS Lambda はイベント駆動型と呼ばれます [5] 。URL にアクセスされたとき、ある時刻になったとき、他の AWS サービスでイベントが発生したとき、様々なことをきっかけに Lambda でプログラムを実行できます。

AWS Lambda はカーシェアリングに例えることができます。カーシェアリングでは必要なときにだけ車を借りることができ、利用した量によって料金が決まります。自分好みに車をカスタマイズしたりはできませんが、車のメンテナンスからは解放されます。

Lambda も同様です。私たちはサーバを保有せず、イベントが発生したときに AWS のサーバでプログラムを実行でき、利用量に応じた料金を支払います。細かいチューニングはできませんが、サーバの管理運用から解放されます。

AWS Lambda の仕組み

AWS Lambda を使うにはまずLambda 関数 [6] を作成します。これは AWS にアップロードしたコードに名前をつけたもので、コードを実行するにあたっての設定を含みます。Lambda 関数を呼び出すとコードが実行されます。

AWS のサーバ上で動作する実行環境の図実行環境はワーカ上に複数起動する (引用 [7])

AWS Lambda で実際にプログラムを実行するのは実行環境 [6] です。実行環境は AWS の物理的なサーバ上に作成された仮想的なサーバです。AWS は 1 台のサーバ上に多数の実行環境を立ち上げることで AWS Lambda のサービスを提供しています。実行環境には Lambda 関数のコードがダウンロードされ、いつでも実行できる状態になっています。

ウォームスタート

Lambda 関数を呼び出したとき、どのようなことが起きるのでしょうか? 同期呼び出し [8] を例に解説していきます。

ウォームスタートの例

図には 2 つの実行環境があります。新しい Lambda 関数呼び出しがあると Lambda サービスは空いている実行環境を探します。この例では待機中の実行環境があるため、そこでプログラムが実行されます。処理が完了すると実行環境は待機状態に戻り、他の呼び出しを処理できるようになります。別のリクエストを処理中の実行環境は他のリクエストを同時には処理できません。

コールドスタート

次は少し別のケースを考えてみましょう。

コールドスタートの例

図には処理中の実行環境が 1 つありますが、待機中の実行環境はありません。このとき Lambda サービスは新しい実行環境を作成して初期化します。その後、準備のできた実行環境に呼び出しを割り当てて処理させます。このように、呼び出しを処理するために新しい実行環境が初期化されることをコールドスタートといいます。反対に既存の実行環境で呼び出しが処理されることをウォームスタート [1] といいます。

コールドスタートでは様々な処理が行われます。シンプルな Lambda 関数では 100 ミリ秒程度ですが、重たい Lambda 関数では数秒かかることもあります [1] 。コールドスタートが長くなるとリクエスト全体の所要時間が長くなってしまいます。

コールドスタートの流れ [1], [9]

  1. 実行環境を立ち上げるサーバを決定する。
  2. サーバに実行環境を立ち上げる。
  3. 実行環境にコードをダウンロードする。
  4. 実行環境でランタイム (AWS Lambda で様々なプログラミング言語を動かすための基盤) を立ち上げる。
  5. 静的初期化コード (ライブラリの読み込み・グローバル変数の初期化など) を実行する。

待機状態がしばらく続いた実行環境は自動的に削除されます。使われない実行環境をいつまでも残しておくのはサーバ資源の無駄遣いだからです。実行環境が削除されるまでの正確な時間は分かりませんが、5 分程度と言われています [10]

レストランに例えてみる

Lambda 関数が呼び出される様子はレストランのそれと似ています。レストランでお客さんが給仕係に注文を伝えると、給仕係は手が空いている料理人に調理をお願いします。料理人はレシピに従って料理を作り、出来上がった料理を給仕係がお客さんに運びます。アナロジーになっていることが分かるでしょうか?

AWS Lambda の用語 レストラン の用語
ユーザ お客さん
Lambda 関数呼び出し 注文
Lambda サービス 給仕係
実行環境 料理人
プログラム レシピ
実行結果 料理

この例えでコールドスタートも考えてみます。開店後のレストランには料理人がいません。1 人目のお客さんがやってくると給仕係が慌てて料理人に出勤を命じます。レストランに来た料理人はまずレシピを熟読します。そのあとにやっと調理が始まって、しばらくしてお客さんに料理が届きます。これではお客さんはかなり待たされてしまうでしょう。

その後はレストランに料理人がいるので、2 人目のお客さんはあまり待たされません。ただし 2 人以上のお客さんが同時に来たときには、料理人 1 人で対応しきれません。別の料理人にも来てもらう必要があり、またお客さんを長く待たせてしまいます。店にしばらく注文がないと料理人たちは勝手に帰っていきます。

無理のある状況設定かもしれませんが、情景を想像して Lambda に親しみを感じてもらえたら嬉しいです。

コールドスタートに悩まされたら

AWS Lambda のコールドスタートによる遅延をどうにかしたいと思うことがあるかもしれません。これを軽減するための方針は大きく分けて次の 2 つです。

  • コールドスタートの所要時間を短くする。
  • コールドスタートの発生を防ぐ。

まずはコールドスタートの発生状況を確認して、次に代表的な対策方法を試してみましょう。

コードスタートの測り方

AWS X-Ray を使うと Lambda 関数の実行時間について詳細な情報を得られます。AWS X-Ray を使った調査方法については こちらの記事 が参考になります。本記事ではログを確認する簡易的な方法をご紹介します。

AWS Lambda のログは AWS マネジメントコンソールの CloudWatch から確認できます 。START, END, REPORT で始まる行は Lambda が自動的に出力したログです。関数呼び出しの開始と終了、統計情報をそれぞれ表します。各行には Lambda 関数の呼び出しを識別する ID も含まれています。 [12]

# AWS Lambda のログの例。横スクロールして Init Duration を確認してください。
START RequestId: c48a3e69-6cd1-456c-b42b-09958599124e Version: $LATEST
END RequestId: c48a3e69-6cd1-456c-b42b-09958599124e
REPORT RequestId: c48a3e69-6cd1-456c-b42b-09958599124e	Duration: 1.39 ms	Billed Duration: 2 ms	Memory Size: 1024 MB	Max Memory Used: 36 MB	Init Duration: 2122.92 ms

最後の行には Init Duration (初期所要時間) [12] が含まれています。コードの読み込みや初期化コードの実行にかかる時間がこれにあたります。コールドスタートの呼び出しのログには Init Duration が含まれますが、ウォームスタートのときには含まれません。

Init Duration はコールドスタートそのものではなく、コールドスタートの一部であることに注意してください。ただし、長いコールドスタートの原因が Init Duration にあることも多いので、これを確認することには意味があります [13]

コールドスタートを短くする

コールドスタートが発生しても 100ミリ秒ならばあまり問題にならないかもしれません。プログラムのデータ量・初期化処理の計算量を減らせばコールドスタートを短くできます。例えば以下のような工夫が有効です [13], [14]

  • 初期化フェーズで重たい処理を実行しない。
  • 軽量なライブラリやフレームワークを使う。
  • プログラムの実行に本当に必要なファイルだけを Lambda にアップロードする。
  • 複雑な機能を持つ Lambda 関数を複数のシンプルな Lambda 関数に分割する。

プログラミング言語に Java を使用している場合は新機能 SnapStart [15] が利用できます。初期化済みの実行環境のスナップショットを事前に作成しておき、コールドスタート時はそのスナップショットから実行環境を復元する機能です。追加の料金なしで Java のコールドスタートを劇的に改善できるとのことで、注目を集めています。

コールドスタート発生を防ぐ

コールドスタートの発生を防ぐには AWS Lambda の機能 Provisioned Concurrency(プロビジョニングされた同時実行数) [16] が効果的です。Provisioned Concurrency の同時実行数に 5 を設定すると、Lambda サービスは少なくとも 5 台の実行環境を常に立ち上げておくようにします。これにより同時に 5 つの呼び出しがあっても、全てウォームスタートになることが期待できます。

Provisioned Concurrency(プロビジョニングされた同時実行数)

実行環境がサーバの資源を占有することもあり、この機能の利用には追加の料金がかかります [17] 。Lambda 関数が呼び出されたかに関係なく費用がかかるので注意してください。また、設定した同時実行数を超える並行の呼び出しに対してはコールドスタートが発生します。コールドスタートを完全に防げるわけではない点にも注意してください。

参考文献

  1. Operating Lambda: パフォーマンスの最適化 – Part 1 | Amazon Web Services ブログ
  2. AWS Lambda(イベント発生時にコードを実行)| AWS
  3. コンピューティングとは? – エンタープライズクラウドコンピューティングの説明 – AWS
  4. サーバーレスコンピューティング – ユースケース別クラウドソリューション | AWS
  5. イベント駆動アーキテクチャ
  6. Lambda の概念 – AWS Lambda
  7. A closer look at AWS Lambda – Awsstatic
  8. Lambda 関数を呼び出す – AWS Lambda
  9. AWS Lambda under the hood (SVS405-R1) – YouTube
  10. Lambda の同一インスタンスはどれくらいの時間が空くと落ちるのか測ったら 5〜6 分くらいだった | mirumi.tech
  11. AWS Lambdaの実行速度をX-Rayで計測する – DevelopersIO
  12. Python の AWS Lambda 関数ログ作成 – AWS Lambda
  13. Operating Lambda: パフォーマンスの最適化 – Part 2 | Amazon Web Services ブログ
  14. AWS Lambda 関数を使用するためのベストプラクティス – AWS Lambda
  15. SnapStart で AWS Lambda 関数の Java コールドスタートを削減する | Amazon Web Services ブログ
  16. プロビジョニングされた同時実行数の設定 – AWS Lambda
  17. 料金 – AWS Lambda |AWS