} return null; 末尾にある参考サイトの内容にたどり着いて、実際に試してみたのでその記録です。, ソース全体 import software.amazon.awssdk.core.sync.RequestBody; import software.amazon.awssdk.services.s3.model.PutObjectResponse; 改めてコンストラクタが実行され、10秒sleepした。 count++; return null;
} package helloworld; com.amazonaws:aws-lambda-java-core (必須) – ランタイムがハンドラーに渡すハンドラーメソッドインターフェイスとコンテキストオブジェクトを定義します。 独自の入力タイプを定義する場合、これが唯一必要なライブラリです。 com.amazonaws:aws-lambda-java-events – Lambda 関数を呼び出すサービ … public Object handleRequest(final Object input, final Context context) { S3 PUT(初回)に時間がかかっているようです。, ソース全体 この記事はSVS403 Best practices for AWS Lambda and Javaのセッションレポートです。 スライドと動画はそれぞれ下記で公開されています。 スライド; 動画; セッション概要. return null; package helloworld; ここでいう実測値とは、手元のストップウォッチを使って計測したという意味です。, ここから推測できることは、コンストラクタは事前に処理されていて、そこは課金対象外になるのかも知れません。, ・・・あれ、それなら、コンストラクタで重い処理をがっつり走らせて、ハンドラでその結果を取り出せば、課金額を抑えられるじゃないですか? PutObjectResponse result = s3.putObject( private static int count = 1; PutObjectRequest.builder().bucket(ENV_BUCKET).key("dummy.txt").build(), import software.amazon.awssdk.services.s3.model.PutObjectResponse; Why not register and get more from Qiita? import com.amazonaws.services.lambda.runtime.RequestHandler; }
}
import software.amazon.awssdk.core.sync.RequestBody; コンストラクタの処理が重い場合は、コンストラクタの処理 + 5秒弱 + ハンドラ内の処理が課金対象となる。, ・・・とは言え、Credentialsの処理をコンストラクタで行った場合に、実測値まで早くなる辺りは、少しだけ不可解です。というか、Credentialsの取得処理が重いこと自体が不可解なのですが。 AWS Lambdaで動作するJavaは初回が遅いですが、速くする方法がないか調べました。 ソースコードがないので推測になりますが、アップロードされたzipをロードして起動する独自コンテナがあり、外部からAPIコールされた際にAWSLambdaクラスあたりが処理を受け取って、zip内のハンドラを呼び出しているのでしょう。, そういえば、もう一つ、謎な挙動がありました。 } ストップウォッチで計測した時間は1から5までの間なので、25秒弱 … import com.amazonaws.services.lambda.runtime.Context; return null;
What is going on with this article? private static int count = 1; public Object handleRequest(final Object input, final Context context) { AWS Lambda内の処理か何かで4秒ぐらい処理が掛かった。 4.
} PutObjectResponse result = s3.putObject( 複数台のサーバで処理されるため、それぞれのサーバでの初回起動時には処理時間が掛かる。 import software.amazon.awssdk.services.s3.model.PutObjectRequest; } 以前のエントリーで、AWS LambdaでJavaを使ってDynamoDBを呼び出した際に、初回起動にとても時間が掛かったという話を書きました。 By following users and tags, you can catch up information on technical fields that you are interested in as a whole, By "stocking" the articles you like, you can search right away. You can run Java code in AWS Lambda. https://dev.classmethod.jp/articles/report-best-practive-for-java-on-lambda/, re:Invent 2019でのセッション資料 In this session, we follow a customer’s journey as they optimize an AWS Lambda function written in Java to meet their cold start time requirements. ところがサーバーレスの代表格であるAWS Lambdaで、ライブラリを含んたzipをアップロードすると初回実行が非常に遅いのです。
AWS PhantomJS lambda ... 4.ルール名を適当に入れて、スケジュール式を「rate(5 minute)」を指定して、送信ボタン .
3回目以降も早くなってますがこれもなにか影響があるのでしょうか?, staticで処理をすれば早くなることがわかりました。 if (count == 1) { ということで、ハンドラの中で10秒スリープする場合と、コンストラクタでスリープした場合の比較をしてみました。, きっちり10秒sleepして、課金対象値もそのオーバーヘッド分ぐらい。ストップウォッチで計測した値も同じく10秒ぐらいになりました。, えーっ、sleepは10秒だったのに、なぜか15秒分ぐらい課金されてしまい、ストップウォッチで計測すると25秒と、えらく時間が掛かりました。これは謎な挙動です。 2. you can read useful information later efficiently. RequestBody.fromString("contents")); public Object handleRequest(final Object input, final Context context) { この辺りはもう少し追試験をしてみれば解析できそうですが、長くなるので、今回はこの辺りまでにしたいと思います。, cero-tさんは、はてなブログを使っています。あなたもはてなブログをはじめてみませんか?, Powered by Hatena Blog static{ S3に1ファイル作成するだけで6秒は遅いですよねぇ。, では昨年末に登場したProvisioned Concurrencyを使うとどうでしょう。 import com.amazonaws.services.lambda.runtime.Context; import software.amazon.awssdk.core.sync.RequestBody;
なるほど、2台のサーバでロードバランシングしているのだと。そのため、それぞれのサーバの初回起動である、1回目と3回目の処理に時間が掛かるのですね。なかなか納得いく結果でした。
https://youtu.be/ddg1u5HLwg8, 他に見つけたブログ } package helloworld; System.out.println(result); S3Client s3 = S3Client.builder().region(Region.AP_NORTHEAST_1).build(); その後、改めてコンストラクタの処理がタイムアウト関係なく実行されたうえで、AWS Lambdaの内部処理と、ハンドラ処理が行われ、すべての処理が課金対象となる、ということころでしょうか。, 今度はSTARTの前に、きちんとBefore waitもAfter waitも出力され、ハンドラ処理のみが課金対象となっていました。, 1. 不思議に思って、CloudWatch Logsのログを確認してみると・・・, 最初のBefore waitの後にAfter waitがなく、Lambdaの処理がSTARTした後に再度Before waitが呼ばれ、After waitした後に、4秒ほど待ってから、ハンドラ処理が実行されてCalledが呼ばれていました。 import software.amazon.awssdk.regions.Region;
Help us understand the problem. import com.amazonaws.services.lambda.runtime.Context; static{
AWS Lambdaで動作するJavaは初回が遅いですが、速くする方法がないか調べました。 末尾にある参考サイトの内容にたどり着いて、実際に試してみたのでその記録です。 レイテンシ情報はX-Rayにて取得しました。 テスト対象. 2〜4の間が課金対象となり、15秒弱となった。 6. private static String ENV_BUCKET = System.getenv("BUCKET"); com.amazonaws.services.lambda.runtime.Context, com.amazonaws.services.lambda.runtime.RequestHandler, software.amazon.awssdk.core.sync.RequestBody, software.amazon.awssdk.services.s3.S3Client, software.amazon.awssdk.services.s3.model.PutObjectRequest, software.amazon.awssdk.services.s3.model.PutObjectResponse, https://aws.amazon.com/jp/blogs/news/new-provisioned-concurrency-for-lambda-functions/, https://dev.classmethod.jp/articles/report-best-practive-for-java-on-lambda/, https://d1.awsstatic.com/events/reinvent/2019/REPEAT_1_Best_practices_for_AWS_Lambda_and_Java_SVS403-R1.pdf, https://pattern-match.com/blog/2020/03/14/springboot2-and-aws-lambda-provisioned-concurrency/, Initialization処理 と staticメソッドによるS3 PUT(1回目)ダミーファイル, S3 PUT(2回目)※Provisionedの際にstaticイニシャライザで1回実行済みのため, you can read useful information later efficiently.
ストップウォッチで計測した時間は1から5までの間なので、25秒弱となった。, 要するに、コンストラクタで重い処理を行うような悪いことを考える人への対策として、コンストラクタは一定時間で(おそらく10秒きっかりで)タイムアウトして、いったんプロセスは破棄される。 5. }, 検証5で早くなったので、Provisioned Concurrencyも組み合わせたら、1回目から速くなるのか?!, ソース全体
System.out.println(result);
} Help us understand the problem. }, お!少し1回目の処理時間がかかるようになって、2回目が少し早くなりましたね。 private static S3Client s3 = S3Client.builder().region(Region.AP_NORTHEAST_1).build(); 4. import software.amazon.awssdk.services.s3.model.PutObjectResponse; import software.amazon.awssdk.services.s3.model.PutObjectResponse; import software.amazon.awssdk.core.sync.RequestBody; 4. System.out.println(result); 一旦staticイニシャライザでダミーファイルを作成してみます。, ソース全体 コンストラクタでCredentialsを取っておくと、実測値で8秒ぐらい、課金対象値で6秒ぐらいでした。 PutObjectResponse result = s3.putObject(
Java性能のパフォーマンス向上における確認実験. PutObjectRequest.builder().bucket(ENV_BUCKET).key("filename.txt").build(), private static String ENV_BUCKET = System.getenv("BUCKET"); System.out.println(result); 独自のコンテナを利用して、モジュールをデプロイしている。
2〜4の間が課金対象となり、15秒弱となった。 RequestBody.fromString("contents")); if (count == 1) {
import software.amazon.awssdk.services.s3.S3Client; Your code runs in an Amazon Linux environment that includes AWS credentials from an AWS Identity and Access Management (IAM) role that you manage. PutObjectResponse result = s3.putObject( if (count == 1) { なるほど、つまりこういうことでしょうか。, 1. import software.amazon.awssdk.services.s3.model.PutObjectRequest; }, Initialization処理が遅いわけじゃないことがわかりました。 import software.amazon.awssdk.services.s3.S3Client; PutObjectResponse result = s3.putObject( ちなみにロードバランシングは毎回このような結果になるわけではなく、1回目と2回目がそれぞれ別のサーバに行く(=処理に時間が掛かる)こともあります。, 先ほど「Tomcatみたいなコンテナ」を使っているんじゃないかと推測しましたが、実際、どんなコンテナを使っているのでしょうか。スレッドダンプを取って、確かめてみました。, 何やらシンプルな独自コンテナを使っているみたいです。何度か実行してみても結果は同じでした。 S3Client s3 = S3Client.builder().region(Region.AP_NORTHEAST_1).build(); private static String ENV_BUCKET = System.getenv("BUCKET");
public Object handleRequest(final Object input, final Context context) { PutObjectResponse result = s3.putObject( 3. return null; 3.
ちなみに回数を重ねるごとにJavaの性能が大きく上がりはするものの、実行開始時の処理時間がかかっている部分をもう少し詳しく知るために、 AWS Lambda上でフィボナッチ数列を求める計算を簡易的にですが各言語毎に調べてみました。
import software.amazon.awssdk.core.sync.RequestBody; ハンドラが実行された。 RequestBody.fromString("contents")); RequestBody.fromString("contents")); import com.amazonaws.services.lambda.runtime.Context; import software.amazon.awssdk.services.s3.model.PutObjectRequest; import software.amazon.awssdk.services.s3.S3Client; | RequestBody.fromString("contents")); count++; }, 1回目だけ遅い、いわゆるコールドスタートが遅い状態ですね。 System.out.println(result); System.out.println(result); import software.amazon.awssdk.services.s3.model.PutObjectResponse; package helloworld;
import software.amazon.awssdk.regions.Region;
public class TestTarget0429 implements RequestHandler