AWS Lambdaでのコールドスタートのメモリの罠と、Invoke Lambdaでのタイムアウトの罠


問題の経緯

API Gateway経由、ALB経由でAPI化しているLambdaを構築していた。
ALB経由Lambdaの中には、VPCに含んでいるものもあった。
そのLambdaからは別のLambdaもいくつかInvokeしていた。
実装を一通り終わってテストしていると、どうもレスポンスが早いときと、遅いとき、酷いとタイムアウト(API Gatewayは30秒制約あるし。。)することがあった。

調査した結果

調査してみると、どうにもInvokeしている部分が怪しかった。
やっぱりVPC Lambdaだとコールドスタートのせいで遅いのかなぁと思いながらログから調査していった。
Invoke自体は実行されているが、何故かInvoke先のLambdaにログが来ていない。。。。
もしかして、コールドスタートから起き上がる前にタイムアウトしてる??と思い、Lambda関連のドキュメントを漁りながら、やっぱりLambdaを定期実行して、コールドスタート回避するしかないのかなぁと思っていると下記の記事を発見。。。。
VPC Lambdaのコールドスタートにお悩みの方へ捧ぐコールドスタート予防のハック Lambdaを定期実行するならメモリの割り当ては1600Mがオススメ?!

マジですか。。
Lambdaのメモリって単に必要分があれば良い程度にしか思ってませんでした。。
こんなことが出来るんですね。。。

ただ、上記設定してみても、それでも若干レスポンスに差がでる。
そこで、Invokeのタイムアウトについて調べると、以下の公式Docが。

AWS SDK を使用して Lambda 関数を呼び出す際の再試行とタイムアウトの問題をトラブルシューティングする方法

なんと。。
私はNodeJSでSDKを使っていたのですが、デフォルトの接続タイムアウトはないと。。。
というか、接続でミスることあるのか。。。同じサービス(AWS)内じゃん。。。。何故。。。

とりあえず、下記のように設定したら、レスポンスは正常になりました。。
色々罠だった。。

XXX.js
AWS.config.update({
  region: "ap-northeast-1",
  maxRetries: 2, // 最大再試行回数
  httpOptions: {
    timeout: 30000, // ソケットタイムアウト
    connectTimeout: 2000 // 接続タイムアウト
  }
});

結論

  • LambdaをInvokeするときは必ず「最大再試行回数」「ソケットタイムアウト」「接続タイムアウト」を設定する
  • Lambdaのメモリは多すぎず、少なすぎず、処理を必ず見てちょうど良いところで設定する(この時、Lambdaの実行時にENIもちゃんと見る)