「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > AWS Lambda での Spring Boot アプリケーション - パート Spring Cloud Function を使用したコールド スタートとウォーム スタートの測定

AWS Lambda での Spring Boot アプリケーション - パート Spring Cloud Function を使用したコールド スタートとウォーム スタートの測定

2024 年 8 月 19 日に公開
ブラウズ:548

Spring Boot pplication on AWS Lambda - Part Measuring cold and warm starts with Spring Cloud Function

導入

パート 8 では Spring Cloud 関数の背後にある概念を紹介し、パート 9 では Java 21 と Spring Boot 3.2 を使用して Spring Cloud Function で AWS Lambda を開発する方法を示しました。このシリーズの記事では、Lambda 関数で SnapStart を有効にするだけでなく、DynamoDB 呼び出しのプライミングや、ネットワークを経由せずに API Gateway リクエスト全体をプライミング (プロキシ) するなど、さまざまなプライミング テクニックを適用するなど、コールド スタートとウォーム スタートの時間を測定します。 。測定には Spring Boot 3.2 サンプル アプリケーションを使用し、すべての Lambda 関数に対して JAVA_TOOL_OPTIONS: "-XX: TieredCompilation -XX:TieredStopAtLevel=1" を使用し、Lambda 1024 MB メモリを与えます。

Spring Cloud Function と Java 21 および Spring Boot 3.2 を使用したコールド スタートとウォーム タイムの測定

まず、Lambda 関数で AWS SnapStart を有効にする方法を説明します。これは (プライミングを最優先にして) Lambda パフォーマンス (特にコールドスタート時間) の最適化の可能性を最大限に高めることができます。それは単に設定の問題です:

SnapStart:
  ApplyOn: PublishedVersions 

は、Lambda 関数のプロパティまたは SAM テンプレートのグローバル関数セクションに適用されます。私たちのユースケースで SnpaStart に加えてさまざまなプライミング技術を使用する方法をさらに詳しく説明したいと思います。プライミングの背後にある考え方については、記事「AWS Lambda SnapStart - プライミング、エンドツーエンドのレイテンシー、デプロイメント時間の測定

」で説明しました。

1) DynamoDB リクエストのプライミング用のコードはここにあります。

このクラスは、CraC プロジェクトの import org.crac.Resource インターフェイスをさらに実装します。

この呼び出しにより

Core.getGlobalContext().register(this);

GetProductByIdWithDynamoDBRequestPrimingHandler クラスは自身を CRaC リソースとして登録します。

さらに、CRaC API から beforeCheckpoint メソッドを実装することで、DynamoDB 呼び出しを準備します。

      @Override
      public void beforeCheckpoint(org.crac.Context extends Resource> context) throws Exception {
             productDao.getProduct("0");
      }

これは、Lambda 関数のデプロイメント段階中、および Firecracker microVM スナップショットが取得される前に呼び出されます。

2) API Gateway リクエスト全体のプライミング用のコードは、ここにあります。

このクラスは、上記の例のように import org.crac.Resource インターフェイスも追加で実装します。
私の記事「AWS Lambda SnapStart - パート 6 Java 11 および Micronaut、Quarkus、Spring Boot フレームワークのリクエスト呼び出しのプライミング」で説明した醜いテクニックを再利用します。この手法を本番環境で使用することはお勧めしませんが、Spring Boot モデルと Spring Cloud Function モデルの間のマッピングと DynamoDB も実行する Lambda モデルを事前にロードすることにより、API Gateway リクエスト全体のプライミングを使用してコールド スタートを削減できる可能性をさらに実証します。呼び出しプライミング。

ID が 0 の /products/{id} の API ゲートウェイ リクエスト構築 API ゲートウェイ JSON リクエストは次のようになります:

      private static String getAPIGatewayRequestMultiLine () {
             return  """
                        {
                      "resource": "/products/{id}",
                      "path":  "/products/0",
                      "httpMethod": "GET",
                      "pathParameters": {
                            "id": "0" 
                        },
                       "requestContext": {
                          "identity": {
                        "apiKey": "blabla"
                      }
                      }
                    }
           """;
      }

API の入力ストリームを渡すことで handleRequest メソッドを呼び出す Spring Cloud Function の FunctionInvoker クラスを使用して、ネットワークを経由せずに API Gateway リクエスト全体をプライム (プロキシ) するときの beforeCheckpoint上記のように構築されたゲートウェイ JSON リクエスト:

@Override
public void beforeCheckpoint(org.crac.Context extends Resource> context) throws Exception {
            
new FunctionInvoker().handleRequest( 
  new ByteArrayInputStream(getAPIGatewayRequestMultiLine().
  getBytes(StandardCharsets.UTF_8)),
  new ByteArrayOutputStream(), new MockLambdaContext());
}

以下の実験の結果は、1024 MB のメモリ設定で Lambda 関数を使用して 100 回を超えるコールド スタートと約 100,000 回のウォーム スタートを 1 時間再現したことに基づいています。このために負荷テスト ツールを使用しましたが、Serverless-artillery や Postman など、好きなツールを使用できます。

これらすべての実験を 4 つの異なるシナリオで実行しました:

1) SnapStart が有効になっていません

template.yaml で次の構成を使用します:

    Handler: org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest    
      #SnapStart:
         #ApplyOn: PublishedVersions      

そして、GetProductByIdHandler Lambda Handler Java クラスにマップされる GetProductByIdWithSpringBoot32SCF という名前の Lambda 関数を呼び出す必要があります。

2) SnapStart は有効ですが、プライミングは適用されていません

template.yaml で次の構成を使用します:

    Handler: org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest 
    SnapStart:
      ApplyOn: PublishedVersions 

そして、GetProductByIdHandler Lambda Handler Java クラスにマップされる GetProductByIdWithSpringBoot32SCF という名前の同じ Lambda 関数を呼び出す必要があります。
3) DynamoDB 呼び出しプライミングで SnapStart が有効になっている

template.yaml で次の構成を使用します:

    Handler: org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest    
    SnapStart:
      ApplyOn: PublishedVersions      

そして、GetProductByIdWithDynamoDBRequestPrimingHandler Lambda Handler Java クラスにマップされる GetProductByIdWithSpringBoot32SCFAndDynamoDBRequestPriming という名前の Lambda 関数を呼び出す必要があります。

4) API Gateway リクエスト呼び出しのプライミング/プロキシで SnapStart が有効になっています

template.yaml で次の構成を使用します:

    Handler: org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest
    SnapStart:
      ApplyOn: PublishedVersions      

そして、名前
でLambda関数を呼び出す必要があります GetProductByIdWithSpringBoot32SCFAndWebRequestPriming。GetProductByIdWithWebRequestPrimingHandler Lambda Handler Java クラスにマップされます。

略語 c はコールド スタート、w はウォーム スタートを表します。

コールド (c) およびウォーム (w) の開始時間 (ミリ秒):

シナリオ番号 c p50 c p75 c p90 c p99 c p99.9 最大値 w p50 w p75 w p90 w p99 w p99.9 最大値
スナップスタートが有効になっていません 4768.34 4850.11 4967.86 5248.61 5811.92 5813.31 7.16 8.13 9.53 21.75 62.00 1367.52
SnapStart は有効ですが、プライミングは適用されていません 2006.60 2065.61 2180.17 2604.69 2662.60 2663.54 7.45 8.40 9.92 23.09 1354.50 1496.46
DynamoDB 呼び出しプライミングで SnapStart が有効になりました 1181.40 1263.23 1384.90 1533.54 1661.20 1662.17 7.57 8.73 10.83 23.83 492.37 646.18
API Gateway リクエスト呼び出しプライミングで SnapStart が有効になりました 855.45 953.91 1107.10 1339.97 1354.78 1355.21 8.00 9.53 12.09 26.31 163.26 547.28

結論

Lambda 関数のみで SnapStart を有効にすることで、Lambda 関数のコールド スタート時間が大幅に短縮されます。さらに DynamoDB 呼び出しプライミングを使用することで、私の記事「AWS SnapStart - 純粋な Lambda のコールド スタートとウォーム スタートを測定した異なるメモリ設定を使用した Java 21 でのコールド スタートとウォーム スタートの測定」で説明したコールド スタートよりもわずかに高いコールド スタートを達成できます。このシナリオのように 1024MB のメモリ設定を含むフレームワークを使用せずに機能します。

記事「AWS サーバーレス Java コンテナーを使用したコールド スタートとウォーム スタートの測定」と「AWS Lambda Web Adaptor を使用したコールド スタートとウォーム スタートの測定」で、AWS サーバーレス Java コンテナーを使用して測定したコールド スタート時間とウォーム スタート時間を比較すると、Spring Cloud Function のコールド スタート時間がより高いことがわかります。開始時間は AWS Lambda Web Adaptor よりも優れていますが、コールド スタート時間は AWS Serverless Java Container とほぼ同等です (結果はパーセンタイルによってわずかに異なります)。ウォーム スタート/実行時間の点では、特に 99.9 未満のパーセンタイルを調べた場合、3 つのアプローチすべてでかなり同等の結果が得られます。

リリースステートメント この記事は、https://dev.to/aws-builders/spring-boot-3-application-on-aws-lambda-part-10-seasuring-cold-and-warm-starts-cold-cloud-function-2b1i?1に再現されています。
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3