The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.

Quarkus の AWS Lambda SnapStartサポート

Quarkus の AWS Lambda SnapStartサポート

Amazon Web Services(AWS)は、AWS LambdaのSnapStart機能を 発表 しました。SnapStart for Javaは、AWS Lambda上で動作するJavaベースの関数の起動レイテンシーを削減します。そして、Quarkusは初日からこれをサポートします!

Quarkusは、クラウドネイティブアプリケーションに特化したsupersonic subatomic Java です。Quarkusの背後にあるアイデアは、従来のフレームワークが実行時に行うことをビルド時に行うことです。Quarkusは、低メモリ使用量と高速起動を実現するように最適化されています。Quarkusは、Javaに 開発者の喜び を取り戻し、すべてのJava開発者が、AWS Lambdaワークロードを含むクラウドネイティブアプリケーションを開発するためにそのスキルを使用できるようにします。

Quarkusでは、 'quarkus-amazon-lambda' エクステンションを使用して、AWS Lambdaへの関数のビルドとデプロイを行っています。このエクステンションにより、開発者はライブコーディング、継続的テストなどのQuarkus開発モデルや、CDI Injectionsや追加のQuarkusエクステンションを使用することができるようになります。開発者は、ネイティブモードまたはJavaモードを使用して、AWS Lambdaに関数をデプロイすることができます。本日の 発表により 、Quarkusで書かれた関数をAWS Lambdaにビルドしてデプロイするためのオプションとして、SnapStart機能が追加されました。

SnapStartとは?

通常、AWS Lambdaは新しい関数を初めて呼び出すときや、トラフィックを処理するためにスケールアップするときに、新しい実行環境を作成します。SnapStartは、初期化された関数の実行環境(メモリやアプリケーションの状態)のスナップショットを取得することで、異なるアプローチを取ります。さらに、そのスナップショットを永続化し、低レイテンシーでアクセスできるようにキャッシュします。関数を呼び出す際、コードや依存関係、フレームワークの初期化に時間を費やす必要はありません。その代わり、Lambdaは永続化されたスナップショットから新しい実行環境を再開します。

SnapStartの考慮事項

SnapStartはスナップショットで動作し、低レイテンシーで実行環境を再開するため、Quarkusで記述された関数にメリットがあります。Quarkusは、Quarkusがサポートするライブラリのスナップショットおよびウォームアップのコードパスを活用できます。

開発者のコードやライブラリに対して、SnapStartを利用する際には、特定のケースを考慮する必要があります:

ネットワーク経由のリソース接続: スナップショットは、関数再開時にリモートホストに接続が戻ることを保証するものではありません。開発者は、接続の状態を確認し、検証する必要があります。 + ソースからのインメモリデータの引き出し :しばしば、別のソースからデータをメモリに取り込む必要があります。この場合、ソースにあるデータが変更されていたり、有効期限が切れていたりすると、不整合になる可能性があります。そのようなデータの状態を確認し、検証してください。+ ランダム性 :Lambda SnapStartは、初期化済の単一のスナップショットを何度も再利用して実行環境を再開することで、アプリケーションを高速化します。その結果、初期化時にスナップショットに含まれていたユニークなコンテンツが、実行環境間で再利用されるため、ユニークさが保てなくなる可能性があります。初期化後にユニークコンテンツが生成されるようにし、初期化中にユニークコンテンツのキャッシュを行わないようにしてください。このようなユニーク性についての考慮事項や、ユニーク性を回復するためにお客様が利用できるインターフェイスについては、機能のドキュメントを参照してください。

Quarkusの高速な起動時間とSnapStartとの統合

典型的なJavaアプリケーションでは、JIT(Just in time)コンパイルが使用されています。アプリケーションの起動時には、特定のウォームアップコードパスがより良いパフォーマンスを発揮するための時間が必要で、これはウォームアップ時間のための追加のCPUサイクルを意味します。クラウド・ネイティブ・アプリケーションは、より高速な起動時間を要求します。AOT(Ahead-of-Time)コンパイルは、ビルド時に最適化のほとんどを行うことで、これを可能にします。その好例がQuarkusです。その結果、起動時からフルスピードで、起動時のコンパイルにかかるCPUオーバーヘッドもありません。Quarkusのアプリケーション初期化には、静的初期化と実行時初期化という2つのフェーズがあります。この区別は、GraalVMのネイティブコンパイルの原則に従っており、静的初期化は結果の実行可能ファイルにインライン化し、実行時初期化は通常の実行中に行われます。我々は、追加した各機能の利点を理解するために、複数の関数を比較しました:

  • Hello関数は、 "Hello" を返すシンプルな関数で、Quarkus AWS Lambdaエクステンションを使用しています。

  • Heroes関数は、DynamoDBの上にCRUDインターフェイスを実装しています。QuarkusのAWS Lamdba HTTPとRESTEasy Reactiveを使用しています。呼び出しは、AWS API Gatewayを経由します。

各関数について、比較します:

  • SnapStartを使用しない場合の起動時間、メモリ、課金期間

  • ウォームアップフェーズとクラスのプリロード中にフル起動した場合の起動時間、メモリ、課金時間。

クラスプリロードは、アプリケーションが使用するすべてのクラスをロードし、初期化します。

結果

Hello Function Without SnapStart With SnapStart Native

合計期間

2230 ms

202 ms

-90.93%

356 ms

-84.05%

課金期間

131 ms

109 ms

-16.79%

356 ms

171.76%

メモリ

115 MB

104 MB

-9.57%

59 MB

-48.70%

Heroes Function Without SnapStart With SnapStart Native

合計期間

15728 ms

965 ms

-93.87%

1112 ms

-92.93%

課金期間

12550 ms

885 ms

-92.95%

1113 ms

-91.13%

メモリ

222 MB

173 MB

-22.07%

96 MB

-56.76%

QuarkusとAWS LambdaのSnapStart関数を組み合わせると、ネイティブのパフォーマンスに近い、通常のJavaよりもはるかに高速な実行時最適化がさらに可能になります。一部の機能では、SnapStartはAWS Lambdaでネイティブ実行可能ファイルをコールドスタートするよりも高速です。その他の機能では、メモリ使用量はネイティブイメージの方が優れています。

結論

AWS Lambdaに関数をビルドしてデプロイするには、JVMモード、Nativeモード、そして今回追加されたSnapStartの3つのオプションがあります。この3つはすべて異なるユースケースを持っています。SnapStartはAWS Lambdaの機能であることに注意することが重要です。

SnapStart機能を使用すると、AWS Lambda環境のネイティブイメージと同様の、場合によってはより高速な起動時間で、QuarkusをJVMモードで実行することが可能です。これを実現するためには、開発者はアプリケーションが安全な状態で起動できること、例えばネットワーク接続やリソースなどを確保する必要があります。幸いなことに、Quarkusを使用している場合、この多くは実施済です。

PR #29108 が Quarkus メイン ブランチにマージされると、Quarkus アプリケーションは AWS Lambda で SnapStart 機能を使用できます。 この機能は、実験的な機能として 2.15 プラットフォーム リリースに組み込まれます。

AWS Lambda ユーザーの場合は、AWS Snapstart の有無にかかわらず Quarkus を試して比較することをお勧めします。 結果とフィードバックをお知らせください。

技術的な詳細については、AWS Lambda SnapStart ブログ こちら にアクセスしてください。