Lambda SnapStart のランタイムフック - AWS Lambda

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

Lambda SnapStart のランタイムフック

ランタイムフックを使用して、Lambda がスナップショットを作成する前、または Lambda がスナップショットから関数を再開した後でコードを実装できます。ランタイムフックは、オープンソースの Coordinated Restore at Checkpoint (CRaC) プロジェクトの一部として提供されています。CRaC は、Open Java Development Kit (OpenJDK) 向けに開発中です。リファレンスアプリケーションで CRaC を使用する方法の例については、GitHub にある CRaC リポジトリを参照してください。CRaC は、3 つの主要要素を使用します。

  • ResourcebeforeCheckpoint() および afterRestore() の 2 つのメソッドを持つインターフェイス。これらのメソッドを使用して、スナップショット前、および復元後に実行するコードを実装します。

  • Context <R extends Resource> – チェックポイントと復元に関する通知を受け取るには、ResourceContext に登録されている必要があります。

  • Core – 静的メソッド Core.getGlobalContext() 経由でデフォルトのグローバル Context を提供するコーディネーションサービス。

Context および Resource の詳細については、CRaC ドキュメントの「Package org.crac」を参照してください。

org.crac package を使用してランタイムフックを実装するには、以下の手順を実行します。Lambda ランタイムには、チェックポイント作成前と復元後にランタイムフックを呼び出す、カスタマイズされた CRaC コンテキスト実装が含まれています。

ステップ 1: ビルド設定を更新する

ビルド設定に org.crac 依存関係を追加します。以下の例は、Gradle を使用しています。他のビルドシステムの例については、Apache Maven ドキュメントを参照してください。

dependencies { compile group: 'com.amazonaws', name: 'aws-lambda-java-core', version: '1.2.1' # All other project dependecies go here: # ... # Then, add the org.crac dependency: implementation group: 'org.crac', name: 'crac', version: '1.4.0' }

ステップ 2: Lambda ハンドラーを更新する

Lambda 関数ハンドラーは、イベントを処理する関数コード内のメソッドです。関数が呼び出されると、Lambda はハンドラーメソッドを実行します。関数は、ハンドラーが応答を返すか、終了するか、タイムアウトするまで実行されます。

詳細については、「Java の AWS Lambda 関数ハンドラー」を参照してください。

以下のハンドラー例は、チェックポイント作成前 (beforeCheckpoint()) と復元後 (afterRestore()) にコードを実行する方法を示しています。このハンドラーは、ランタイムが管理するグローバル Context への Resource の登録も行います。

注記

Lambda がスナップショットを作成するときは、初期化コードが最大 15 分間実行される場合があります。制限時間は 130 秒、または設定されている関数のタイムアウト (最大 900 秒) のいずれか長い方です。beforeCheckpoint() ランタイムフックは初期化コードの時間制限にカウントされます。Lambda がスナップショットを復元するときは、タイムアウト制限 (10 秒) 内にランタイム (JVM) がロードされ、afterRestore() ランタイムフックが完了される必要があります。その時間を超えると、SnapStartTimeoutException が発生します。

... import org.crac.Resource; import org.crac.Core; ... public class CRaCDemo implements RequestStreamHandler, Resource { public CRaCDemo() { Core.getGlobalContext().register(this); } public String handleRequest(String name, Context context) throws IOException { System.out.println("Handler execution"); return "Hello " + name; } @Override public void beforeCheckpoint(org.crac.Context<? extends Resource> context) throws Exception { System.out.println("Before checkpoint"); } @Override public void afterRestore(org.crac.Context<? extends Resource> context) throws Exception { System.out.println("After restore");

Context は、登録されたオブジェクトへの WeakReference のみを維持します。Resource に対してガベージコレクションが行われた場合、ランタイムフックは実行されません。ランタイムフックが実行されることを保証するには、コードが Resource への強参照を維持する必要があります。

以下は、避ける必要があるパターンの 2 つの例です。

例 – 強参照がないオブジェクト
Core.getGlobalContext().register( new MyResource() );
例 – 匿名クラスのオブジェクト
Core.getGlobalContext().register( new Resource() { @Override public void afterRestore(Context<? extends Resource> context) throws Exception { // ... } @Override public void beforeCheckpoint(Context<? extends Resource> context) throws Exception { // ... } } );

これらの代わりに、強参照を維持します。以下の例では、登録されたリソースに対してガベージコレクションが行われず、ランタイムフックが一貫的に実行されます。

例 – 強参照を持つオブジェクト
Resource myResource = new MyResource(); // This reference must be maintained to prevent the registered resource from being garbage collected Core.getGlobalContext().register( myResource );