serverless frameworkでAWS Lambdaを開発してハマった話とか

serverless frameworkを使ってAWS Lambda関数の開発をしていて、メモリ周りでちょっと困ったことになったので、覚書。

 

一応この記事の続き。

kdnakt.hatenablog.com

 

 

[serverless frameworkのデフォルトメモリサイズは1024MB]

serverless frameworkを利用した場合、デフォルトのメモリサイズは1024MBとなる。

 

このことは、ドキュメントにもきちんと注意点として、記載されている。

memorySize: 512 # Overwrite the default memory size. Default is 1024

serverless.com

 

ところが、AWS Lambdaのデフォルトのメモリサイズは128MBである。

f:id:kidani_a:20180818020849p:plain

 

普段AWS Management Console上で何も考えずにPythonやnode.jsを選択して既存ソースをコピペしてLambdaをちょろっと動かしてみるなんてことをよくやるが、毎回Lambdaのメモリサイズはデフォルトで最低値の128MBになっている。

なので、serverless frameworkを利用するときも同様だろうと思って十分に確認せずに利用していたが、実際は違った。

 

違って何が困るかといえば、お金だ。

 

[AWS Lambdaのメモリサイズと料金(2018年8月時点)]

AWS Lambdaの料金は指定されたメモリ量(実際に使用したメモリ量ではない)と100ミリ秒単位の実行時間(切り上げ)によって決定される。

 

aws.amazon.com

 

128MBのメモリで100ms実行すると、$0.000000208。

1024MBのメモリで100ms実行すると、$0.000001667。

メモリが8倍になると、料金も約8倍になっている。

 

f:id:kidani_a:20180818022138p:plain

画像は何も知らずにaws-go-depテンプレートで作成したLambda関数を実行した際にCloudWatchに記録されたログである。

 

実行時間は132.77msに対して、課金時間は200msで切り上げられている。それはいい。

 

メモリサイズは1024MBが指定されているが、実際に利用されたメモリの最大量は37MBとある。10分の1もメモリを使えていない(hello worldのメッセージを返すだけの処理なので当たり前なのだが)。これではあまりにお金が勿体無い。

仮に同じ処理が月に500万回実行されるとすると、無料枠などの条件を考慮せず単純に考えた場合、以下のようになる。

 

  • 128MBの場合:$2.08
  • 1024MBの場合:$16.67

 

Lambdaなのでどちらの場合もかなり安いが、出費は少ない方が良い。無駄なリソースは確保しないように適切に設定するよう注意が必要である。

 

[マージされなかった修正]

2年前の2016年時点で、serverless frameworkのメモリサイズのデフォルト値に関するIssueが起票されたものの、残念ながら却下されている*1

github.com

github.com

Core DeveloperのPhilipp Muens氏曰く、

We've figured that 1024 is the memory size most real world applications need to run smoothly. That's why we added it as a default.

 とのこと。

一体どんな処理でそんなにメモリが必要になるのだろう……自分が普段あまり扱うことのない画像や音声に関する処理や、機械学習絡みの処理なのだろうか。

 

ところで、アイコンが同じなので多分上記Issueを起票したのと同じ人だと思うけれど、この注意点はQiitaにもしっかりと記事が上がっていた。残念ながらserverless frameworkを使う前に、この問題点を知ることは出来なかったが……。

qiita.com

 

[まとめ]

  • フレームワークを使う場合は公式ドキュメントでデフォルト値をチェックする
  • ドキュメントを読まない場合は「(フレームワーク名) 注意点」などでググって既知の注意点・問題点を確認する
  • serverless frameworkを使う場合は、serverless.ymlで必ず適切なメモリサイズを設定する
  • 可能であれば自前のserverless用テンプレートymlを作ってそちらを再利用する

 

因みにserverless.ymlのメモリサイズの設定例は以下の通り。 

provider:
  name: aws
  runtime: nodejs6.10
  memorySize: 128 # Overwrite the default memory size. Default is 1024

 

今日のブログ執筆BGMはこちら。

www.youtube.com

*1:個人的にはIssueのやりとりにもあったように、AWS Lambdaのデフォルトに合わせてくれよ……という気持ち。