AWS Lambda SnapStartを使ってみる
はじめに
業務開発案件ではよく使われているJavaなのですが、AWS LambdaでJavaを使う場合には、コールドスタート時の初期化時間が特に遅く問題になります。それを解決する手段としてSnapStartという機構が用意されています。
発表当時はJava11のみの対応だったのですが、現在はJava11, 17, 21に対応しています。SnapStartを検証してみました。
SnapStartを試してみる
SnapStartでコールドスタートが高速化することについては、いろんな記事で言及があるので、この記事では触れません。
SnapStartでは、初期化コードが実行された状態で保存され、コールドスタート時には初期化された状態がリストアされて実行されます。
デプロイまで
こちらのサンプルコードでは、hogeSeedという変数にstatic初期化ブロックでランダムなUUIDを設定するという処理をしています。
通常のコールドスタート時には、クラスの生成から行われるためhogeSeedの値は変化します。(ただしウォームスタート時には同じインスタンスが使用されるので変わらない)
一方でSnapStartが使用されていとと、あらかじめ初期化コードが実行された状態が保存され、初期化コードが実行済みの状態が復元されるためhogeSeedの値は同じ値になります。
スナップショット化プロセスが分かりやすいように、ランタイムフックが使用できます。ランタイムフックの使用は任意です。
ランタイムフックを実装すると以下のようになります。ランタイムフックのメソッド beforeCheckpointと、afterRestoreがSnapStartのときに使用されるイベントのように機能します。
この状態でデプロイし、バージョンを作成すると初期化コードが実行され、beforeCheckpointが実行されました。
このとき3つのhogeSeedが作られたインスタンスが保存されたようになります。
余談ですがSnapStartを使うにはバージョンが必要です。最初わからずに$LatestでSnapStartを使おうとして適用されずにハマりました。特定のバージョンでLambdaを呼び出すことになります。
このSnapStartが設定され、初期化状態が保存された状態のLambdaを起動すると、初期化のプロセスは行われず代わりにRestoreが呼び出され初期化済みの状態が復元されます。
実行
この状態で、同時実行が発生するように呼び出してみると、初期化コードで生成されたhogeSeedが使用されていることがわかります。
時間が経ってコールドスタートしてもこのhogeSeedの値は同様になります。
コールドスタートのときに初期化が行われずRestoreが行われていることがわかりました。
まとめ
AWS LambdaでJavaコードを使う際にSnapStart を適用して初期化コードをスキップする方法を紹介しました。
SnapStartを使うことでコールドスタード時の処理を短縮できます。一方で初期化コードの結果が保存されるので注意が必要なことを紹介しました。
この記事が気に入ったらサポートをしてみませんか?