AWS Lambdaの実行速度をX-Rayで計測する
Introduction
AWS Lambdaのコールドスタート・ウォームスタートにかかった時間を
計測する必要があったので、測定方法について
社内で聞いたところ、下記のような意見をいただきました。
- CW Logsに出力されるLambdaのログ見ればCW LogsInsightsとかで分析できる
- 単純な時間の計測だけならX-Rayが手軽
- Lambda→Lambda呼び出しで計測できる
- 視覚的にボトルネックを把握したいとかであればX-Rayが便利
- 何度も計測して結果を集計したいなら自前で計算が必要なので、CloudWatch Lambda Insightsが楽
今回は簡単にいきたいため、X-Rayを使って計測しました。
AWS X-Ray?
AWS X-Rayはアプリケーションの分析やデバッグ用サービスです。
アプリに対するリクエストされたデータを収集&分析して詳細な情報を確認できます。
もちろん、AWS Lambdaに対しても適用可能になってます。
対象のLambda関数でアクティブトレースを有効化して適切なロールを付与すると、
実行時にデータをX-Rayに送信し、X-Rayはデータを処理して分析情報を生成します。
X-Rayはサービスによって処理されるリクエストに関する情報を記録します。
Lambdaの場合、後述するInitialization、Invocation、Overhead
のサブセグメントの情報が記録されます。
Initialization
Lambda実行環境ライフサイクルの初期フェーズ。
コールドスタートにかかる時間がこれになります。
設定したリソースを使用して実行環境を作成(もしくはフリーズ解除)し、
関数とすべてのレイヤーをダウンロード後にランタイムの初期化と関数の初期化を実施します。
Invocation
Lambdaが関数ハンドラを呼び出すフェーズ。
ランタイムと拡張機能の登録、ランタイムがレスポンスを送信する準備ができたら終了です。
Overhead
ランタイムが応答を送信してから、次の呼び出しのシグナルを送信するまでに発生するフェーズ。
Environment
以下の環境で試しました。 aws cliは実行可能な前提です。
- OS : MacOS 11.3.1
- Node: 16.2
Measure Speed (Javascript)
Lambda作成
では適当なLambda関数を定義し、X-Rayで測定してみましょう。
AWSコンソールのLambda画面で、Nodeランタイムの関数を作成します。
関数の内容はなんでもよいです。
今回は↓のような内容のLambdaをAWSコンソール上で記述しました。
exports.handler = async (event, context) => { const response = { statusCode: 200, body: JSON.stringify('Hello from Lambda!'), }; return response; }
X-ray設定
設定 > モニタリングおよび運用ツール > 編集
と進み、AWS X-RayのアクティブトレースをOnにして保存しましょう。
これでLambda実行結果をX-Rayで確認できます。
Lambda実行
登録したLambdaを実行します。
AWSコンソールのテストタブからでもいいし、
aws cliのlambda invokeでもかまいません。
X-Rayみてみる
コンソールでX-rayへいき、計測結果を確認してましょう。
初回であればInitializationの項目があり、コールドスタートしているのがわかります。
Appendix
ツール使ってやってみる
1回だけならさきほどのような手動実行でいいのですが、
回数が増えると手間です。
今回調査するにあたって雑にLambda実行とX-ray計測のスクリプトを作りました。
※ リージョン/実行方法/結果取得時間 とかはかなり適当
このnodeプログラムを↓のように実行して、
% node run-lambda.js run <Lambda関数名> <実行回数>
↓でX-Ray結果を取得しました。
% node parse-xray.js
いくつかの言語で計測した
Node(Javascript)以外にも、Deno、Rust、Go、JavaでLambdaを定義して計測してみました。
言語 | ランタイム | メモリ | コードサイズ | リージョン |
---|---|---|---|---|
Python | Python 3.9 | 128M | 299.0 byte | us-west-2 |
Go | Go 1.x | 128M | 4.2 MB | us-west-2 |
Javascript | Node 14.x | 128M | 251.0 byte | us-west-2 |
Rust | Custom runtime on Amazon Linux 2 | 128M | 2.3 MB | |us-west-2 |
Deno(TypeScript) | Custom runtime on Amazon Linux 2 | 128M | 8.4 MB | us-west-2 |
Java | Java 11 (Corretto) | 128M | 342.0 byte | us-west-2 |
結果は↓です。Javaのコールドスタートがぶっちぎりで遅い。
*Lambda関数を各100回実行した平均