Amazon Web Services ブログ

Python および .NET 関数向けの AWS Lambda SnapStart の一般提供を開始

11 月 18 日、Python および .NET 関数向けの AWS Lambda SnapStart の一般提供の開始を発表しました。これにより、関数の起動パフォーマンスが数秒からわずか 1 秒未満にまで高速化され、通常は Python、C#、F#、Powershell におけるコード変更が最小限またはまったく不要になります。

2022 年 11 月 28 日、Java 関数向けの Lambda SnapStart をリリースし、起動パフォーマンスを最大 10 倍改善しました。Lambda SnapStart を使用すると、リソースをプロビジョニングしたり、複雑なパフォーマンス最適化の実装に時間を費やしたりすることなく、関数の初期化から生じる異常なレイテンシーを低減できます。

Lambda SnapStart は、1 回限りの初期化コード、または Lambda 関数が最初に呼び出されたときにのみ実行されるコードのスナップショットされたメモリとディスクの状態をキャッシュして再利用することで機能します。Lambda は、初期化された実行環境のメモリとディスクの状態の Firecracker microVM スナップショットを取得し、そのスナップショットを暗号化して、低レイテンシーのアクセスのためにキャッシュします。

関数バージョンを初めて呼び出し、その後呼び出しがスケールアップしていく中で、Lambda は最初から初期化するのではなく、キャッシュされたスナップショットから新しい実行環境を再開し、起動レイテンシーを改善します。Lambda SnapStart では、AWS Lambda を使用して、Python および .NET で高度にスケーラブルで応答性の高いアプリケーションを簡単に構築できます。

Python 関数の場合、初期化コードからの起動レイテンシーは数秒に及ぶ場合があります。これが発生する可能性があるシナリオには、依存関係のロード (LangChain、Numpy、Pandas、DuckDB など) やフレームワークの使用 (Flask や Django など) が含まれます。また、多くの関数は、Lambda を使用して機械学習 (ML) 推論も実行し、初期化中に ML モデルをロードする必要があります。このプロセスには、使用するモデルのサイズに応じて数十秒かかる場合があります。Lambda SnapStart を使用すると、これらのシナリオで起動レイテンシーを数秒からわずか 1 秒未満に低減できます。

.NET 関数の場合、.NET ジャストインタイム (JIT) コンパイルには最大数秒かかるため、ほとんどのユースケースで恩恵を享受できると考えています。Lambda 関数の初期化に関連するレイテンシーの変動性は、長年にわたって、お客様が AWS Lambda で .NET を使用する上での障壁となってきました。SnapStart を使用すると、メモリとディスクの状態のスナップショットをキャッシュすることで、関数を迅速に再開できます。そのため、ほとんどの .NET 関数では、Lambda SnapStart によってレイテンシーの変動性が大幅に改善されます。

Python および .NET 向けの Lambda SnapStart の開始方法
使用を開始するには、AWS マネジメントコンソールAWS コマンドラインインターフェイス (AWS CLI)、または AWS SDK を使用して、Python および .NET 関数向けの SnapStart をアクティブ化、更新、および削除できます。

AWS Lambda コンソールで、[関数] ページに移動し、Lambda SnapStart を使用する関数を選択します。[設定][一般設定][編集] の順に選択します。[SnapStart] の設定は、[基本設定を編集] ページで確認できます。

Python 3.12 以降、および .NET 8 以降のマネージドランタイムを使用して、Lambda 関数をアクティブ化できます。[公開バージョン] を選択し、[保存] を選択します。

関数の新しいバージョンを公開すると、Lambda はコードを初期化し、初期化された実行環境のスナップショットを作成してから、低レイテンシーでのアクセスのためにスナップショットをキャッシュします。関数を呼び出して、SnapStart のアクティブ化を確認できます。

update-function-configuration コマンドを --snap-start オプションとともに実行して関数設定を更新する AWS CLI コマンドを次に示します。

aws lambda update-function-configuration \
  --function-name lambda-python-snapstart-test \
  --snap-start ApplyOn=PublishedVersions

publish-version コマンドを使用して関数バージョンを公開します。

aws lambda publish-version \
  --function-name lambda-python-snapstart-test

get-function-configuration コマンドを実行してバージョン番号を指定することで、関数バージョンのために SnapStart がアクティブ化されていることを確認します。

aws lambda get-function-configuration \
  --function-name lambda-python-snapstart-test:1

レスポンスで OptimizationStatusOn で、StateActive であることが示されている場合、SnapStart はアクティブ化されており、指定された関数バージョンのスナップショットを使用できます。

"SnapStart": { 
    "ApplyOn": "PublishedVersions",
    "OptimizationStatus": "On"
 },
 "State": "Active",

AWS SDK、AWS CloudFormationAWS サーバーレスアプリケーションモデル (AWS SAM)AWS Cloud Development Kit (AWS CDK) を使用してスナップショットをアクティブ化、更新、削除する方法の詳細については、「AWS Lambda デベロッパーガイド」の「Lambda SnapStart のアクティブ化と管理」にアクセスしてください。

ランタイムフック
ランタイムフックを使用すると、Lambda がスナップショットを作成する前、または Lambda がスナップショットから関数を再開した後に実行されるコードを実行できます。ランタイムフックは、クリーンアップオペレーションやリソース解放オペレーションの実行、設定や他のメタデータの動的な更新、通知の送信や外部状態の更新などの外部サービスやシステムとの統合、依存関係の事前ロードなどの関数の起動シーケンスのファインチューニングに役立ちます。

Python ランタイムフックは、Python マネージドランタイムに含まれるオープンソースの Snapshot Restore for Python ライブラリの一部として使用できます。このライブラリは、Lambda がスナップショットを作成する前に実行されるデコレーター @register_before_snapshot と、Lambda がスナップショットから関数を再開するときに実行されるデコレーター @register_after_restore の 2 つを提供します。詳細については、「AWS Lambda デベロッパーガイド」の「Lambda SnapStart runtime hooks for Python」にアクセスしてください。

チェックポイント作成前と復元後にコードを実行する方法を示す Python ハンドラーの例を次に示します。

from snapshot_restore_py import register_before_snapshot, register_after_restore

def lambda_handler(event, context):
    # ハンドラーコード

@register_before_snapshot
def before_checkpoint():
    # スナップショットを作成する前に実行されるロジック

@register_after_restore
def after_restore():
    # 復元後に実行されるロジック

また、NuGet の Amazon.Lambda.Core パッケージ (バージョン 2.4 以降) の一部として使用できる .NET ランタイムフックを使用することもできます。このライブラリは、スナップショットの作成前に実行する RegisterBeforeSnapshot() と、スナップショットから関数を再開した後に実行する RegisterAfterRestore() の 2 つのメソッドを提供します。詳細については、「AWS Lambda デベロッパーガイド」の「Lambda SnapStart runtime hooks for .NET」にアクセスしてください。

チェックポイント作成前と復元後にコードを実行する方法を示す C# ハンドラーの例を次に示します。

public class SampleClass
{
    public SampleClass()
    { 
        Amazon.Lambda.Core.SnapshotRestore.RegisterBeforeSnapshot(BeforeCheckpoint); 
        Amazon.Lambda.Core.SnapshotRestore.RegisterAfterRestore(AfterRestore);
    }
    
    private ValueTask BeforeCheckpoint()
    {
        // スナップショットを作成する前に実行されるロジックを追加します
        return ValueTask.CompletedTask;
    }

    private ValueTask AfterRestore()
    {
        // スナップショットを復元した後に実行されるロジックを追加します
        return ValueTask.CompletedTask;
    }

    public APIGatewayProxyResponse FunctionHandler(APIGatewayProxyRequest request, ILambdaContext context)
    {
        // INSERT business logic
        return new APIGatewayProxyResponse
        {
            StatusCode = 200
        };
    }
}

お好みのランタイムのランタイムフックを実装する方法については、「AWS Lambda デベロッパーガイド」の「Lambda 関数スナップショットの前後のコード実装」にアクセスしてください。

知っておくべきこと
Lambda SnapStart について知っておくべきことをいくつかご紹介します。

  • 一意性の取り扱い – 初期化コードがスナップショットに含まれる一意のコンテンツを生成した場合、複数の実行環境で再利用されると、そのコンテンツは一意ではなくなります。コードが組み込みライブラリに依拠しないカスタム乱数生成を使用したり、初期化中に期限切れになる可能性のある DNS エントリなどの情報をキャッシュしたりする場合などにおいては、SnapStart を使用する際に一意性を維持するには、初期化後に一意のコンテンツを生成する必要があります。一意性を復元する方法については、「AWS Lambda デベロッパーガイド」の「Lambda SnapStart での一意性の取り扱い」にアクセスしてください。
  • パフォーマンスのチューニング – パフォーマンスが最大限に発揮されるようにするには、関数ハンドラーではなく初期化コードで依存関係を事前ロードし、起動レイテンシーに影響するリソースを初期化することをお勧めします。これにより、大量のクラスロードに関連するレイテンシーが呼び出しパスから外れ、SnapStart による起動パフォーマンスが最適化されます。
  • ネットワーキングのベストプラクティス – Lambda がスナップショットから関数を再開する場合、初期化フェーズ中に関数が確立する接続の状態は保証されません。ほとんどの場合、AWS SDK が確立したネットワーク接続は自動的に再開されます。他の接続については、「AWS Lambda デベロッパーガイド」の「Lambda SnapStart パフォーマンスの最大化」をご覧ください。
  • モニタリング関数Amazon CloudWatch ログストリーム、AWS X-Ray アクティブトレース、ならびに Telemetry APIAmazon API Gateway、および関数 URL メトリクスを使用した拡張機能のリアルタイムテレメトリデータへのアクセスを使用して、SnapStart 関数をモニタリングできます。SnapStart 関数の違いの詳細については、「AWS Lambda デベロッパーガイド」の「Lambda SnapStart のモニタリング」にアクセスしてください。

今すぐご利用いただけます
Python および .NET 関数向けの AWS Lambda SnapStart は、米国東部 (バージニア北部)、米国東部 (オハイオ)、米国西部 (オレゴン)、アジアパシフィック (シンガポール)、アジアパシフィック (シドニー)、アジアパシフィック (東京)、欧州 (フランクフルト)、欧州 (アイルランド)、欧州 (ストックホルム) の AWS リージョンで現在ご利用いただけます。

Python および .NET マネージドランタイムでは、2 種類の SnapStart 料金があります。すなわち、SnapStart を有効にした状態で公開する関数バージョンごとにスナップショットをキャッシュするコストと、関数インスタンスがスナップショットから復元されるたびにかかる復元コストです。そのため、SnapStart キャッシュコストを削減するには、未使用の関数バージョンを削除してください。詳細については、AWS Lambda の料金ページにアクセスしてください。

AWS Lambda コンソールで Python および .NET 向けの Lambda SnapStart をぜひお試しください。詳細については、Lambda SnapStart のページにアクセスしてください。また、AWS Lambda の AWS re:Post または通常の AWS サポートの連絡先を通じてフィードバックをぜひお寄せください。

Channy

原文はこちらです。