起こった現象
LambdaをRuby実装で使っていました。AWS SAM CLIを利用して開発を行っていました。開発自体は何事もなくすすんでいたのですが、機能追加のためにAWS SDKを使うように変更したところ sam local
がすごく遅くなったのでした。こんな簡単なサンプルアプリでここまで遅くなるのはおかしいでしょ…と調べてみました。
サンプルプロジェクトはこちら
※deployして試したあとはstack及びcloudwatchのロググループを忘れずに削除してください!
さっさと結論だけ
Lambdaのランタイムには、各環境に合わせてAWS SDKがインストールされているのでLambdaのデプロイパッケージには含めなくてもよいです。
特にRubyであれば Gemfileへの「gem 'aws-sdk', '~> 3'」のような記載は不要 です!
普段利用するGemをGemfileに書く癖がついているとすごく気持ち悪いですが、グローバルなgemにインストールされたgemはそのままrequireできますので問題ないです。
Gemfileに「gem 'aws-sdk', '~> 3'」を書いた場合(修正前)と、削除(修正後)して比較する
Gemfileに書くかどうかでpackageのサイズが大きく変わります(AWS SDKだけで23M近くある)ので、その差が大きくでる結果となりました。
ちなみに修正前だと sam local
はかろうじて動きましたのでその比較だけ。デプロイ後はLambdaのメモリ及びタイムアウト時間をかなり伸ばさないとうまく動きませんでした。
修正前
Init Duration: 54544.65 ms
とかなり時間がかかります。
$ sam local invoke HelloWorldFunction --event events/event.json --env-vars env.json
Invoking app.lambda_handler (ruby2.5)
Fetching lambci/lambda:ruby2.5 Docker container image......
Mounting /home/ubuntu/environment/test/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container
START RequestId: 22ddc38d-745a-1d37-0ce9-324760f75ec4 Version: $LATEST
END RequestId: 22ddc38d-745a-1d37-0ce9-324760f75ec4
REPORT RequestId: 22ddc38d-745a-1d37-0ce9-324760f75ec4 Init Duration: 54544.65 ms Duration: 801.49 ms Billed Duration: 900 ms Memory Size: 128 MBMax Memory Used: 60 MB
{"statusCode":200,"body":"{\"message\":\"t2.micro\"}"}
修正後
Init Duration: 2266.99 ms
と改善!
$ sam local invoke HelloWorldFunction --event events/event.json --env-vars env.json
Invoking app.lambda_handler (ruby2.5)
Fetching lambci/lambda:ruby2.5 Docker container image......
Mounting /home/ubuntu/environment/test/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container
START RequestId: a81dffd9-915d-13db-3ed7-4fe0e3b63464 Version: $LATEST
END RequestId: a81dffd9-915d-13db-3ed7-4fe0e3b63464
REPORT RequestId: a81dffd9-915d-13db-3ed7-4fe0e3b63464 Init Duration: 2266.99 ms Duration: 557.91 ms Billed Duration: 600 ms Memory Size: 128 MBMax Memory Used: 58 MB
{"statusCode":200,"body":"{\"message\":\"t2.micro\"}"}
最後に
Lambdaを使うならサイズやパフォーマンスには注意を払わないと余計な費用が掛かってしまいますね。処理時間もパッケージサイズも軽く。Lambdaの分割や、AWS Lambda Layersなども使って対応していきたいと思います。