昨年のre:Inventで、AWSはFaaS提供のAWS Lambdaのアップデートとして、Java Functionsのコールドスタートを軽減するLambda SnapStart機能を発表した。
AWS Lambdaの関数は、安全に隔離された環境内で実行され、各環境のライフサイクルは3つのフェーズInit、Invoke、Shutdownで構成される。最初のフェーズであるInitでは関数のランタイムをブートストラップし静的コードを実行する。
Javaなど一部の言語では、Spring Boot、Quarkus、Micronautなどのフレームワークと連携したランタイムの場合、最初のフェーズInitに10秒程度かかることもある(これには依存性注入、コードのコンパイル、クラスパス・コンポーネントのスキャンが含まれる)。さらに静的なコードではいくつかの機械学習モデルのダウンロードや参照データの事前計算、他のAWSサービスへのネットワーク接続を処理する場合もある。
関数に対してLambda SnapStartを有効にすると、関数の新バージョンを公開することで最適化プロセスが起動する。AWSのチーフエバンジェリストであるJeff Barr氏は、同社のニュースブログの記事で次のように説明している:
このプロセスは関数を起動し、Initフェーズ全体を通して実行します。その後、メモリとディスクの状態の不変で暗号化されたスナップショットを取得し、再利用のためにキャッシュします。その後、関数が呼び出されると、必要に応じてキャッシュから状態が取得され、実行環境の構築に使用されるのです。この最適化により、新しい実行環境の作成に専用のInitフェーズが不要になるため、呼び出し時間が短縮され、予測しやすくなります。
なお、キャッシュされたスナップショットは、14日間使用されないと削除される。また、DatadogのリードソフトウェアエンジニアであるAJ Stuyvenberg氏は、dev.toのブログ記事で次のように説明している:
このスナップショット機能は、AWS Fargateと同様にLambdaで使用される基礎的なMicroVMフレームワークであるFireCracker内のMicroVM Snapshotテクノロジーによって実現されています。実際にはファンクションハンドラーコードがサブセカンド・レイテンシーで実行を開始できることを意味します(最大で10倍速)。
Source: https://dev.to/aws-builders/introducing-lambda-snapstart-46no
AWSは、Lambda SnapStartは同期型API、対話型マイクロサービス、またはデータ処理アプリケーションに最適であると述べている。
開発者は、AWS Lambda API、AWS Management Console、AWS Command Line Interface(AWS CLI)、AWS Cloud Formation、AWS Serverless Application Model(AWS SAM)、AWS SDK、AWS Cloud Development Kit(AWS CDK)を使用してAmazon Corretto 11で実行する新規または既存のJavaベースのLambda関数のLambda SnapStartを有効にすることが可能だ。
Javaのサポートについては、Redditのスレッドで回答者がこう書いている:
これは非常にクールな新機能で、コールドスタートをほぼ無くすことができるようである。
これがJavaだけなのは残念だが、いずれ他のランタイムにも対応することを期待している。実装はJVMに特化したものではなさそうだ。
とはいえJVMはLambdaでコールドスタートがもっとも差し支えるため、JVMから対応したのはよかったと思う。
現在、Lambda SnapStartは、US East(オハイオ、N.バージニア)、US West(オレゴン)、アジアパシフィック(シンガポール、シドニー、東京)、ヨーロッパ(フランクフルト、アイルランド、ストックホルム)のリージョンで利用可能である。