業務では、C#でAWS Lambdaをでゴリゴリに使い倒すことが多いのですが、 先日、短期間に連続してLambdaを実行すると意図したレスポンスが得られないというバグが発生し、半日程溶かしてしまいました。 戒めとして、Lambdaでの静的メンバーの扱いについて調べた結果を残しておきたいと思います。
結論
- Lambdaのウォームスタート時にはC#の静的メンバーはキャッシュされたものが利用される
短時間にLambdaを連続して実行すると、前回実行した際の静的メンバーの値が次のウォームスタート時にも保持されます。 この仕様を理解せずにコーディングしていた為にバグが起こっていた模様。
Lambda実行時には何が行われているのか
Lambdaを実行すると「コールドスタート」または「ウォームスタート」として処理が実行されます。
コールドスタート時の処理 | ウォームスタート時の処理 |
---|---|
①S3からコードをDL | ①コードの実行 |
②コンテナの作成 | |
③コードの初期化 | |
④コードの実行 |
初回のLambda実行時は「コールドスタート」として処理が実行され、実行後5分間はLambdaインスタンスは保持されます。 インスタンスが保持されている期間内に再度実行すると、「ウォームスタート」として処理が実行されます。
ウォームスタート時はLambdaインスタンスのメモリにコードが読み込まれた状態なので、すぐにビジネスロジックの実行が出来ます。 つまり、短期間に連続実行する場合は2回目以降の実行時間が大幅に削減されるということですね。 実際開発でテスト等をしていると、C#でのLambdaのコールドスタートは、ウォームスタートの倍以上の実行時間がかかっているので嬉しい機能です。
では、静的メンバーはいつロードされるのか
「コールドスタート時にコンテナにロード」されます。 ウォームスタート時には初期化されません。
これを知らずに安易に静的メンバーを操作するようなソースコードを書いていた為にハマってしまった訳です。 Lambdaはビジネスロジックに集中できて大変便利ですが、内部の処理の理解もやはり必要ですね。
参考
Lambda Performance Optimization: 12 Tips & Advanced Tuning | Lumigo