AWS Lambdaを1分間隔より短い間隔で定期実行させる

やりたいこと

タイトルの通りです。

AWS LambdaのトリガとしてCloudWatch Events Schedule を指定することで、Lambdaを定期実行することができます。

docs.aws.amazon.com

しかし、Unix系OSのCronと同様、1分間隔より短い間隔を指定することはできません。

Rate または Cron を使用したスケジュール式 - AWS Lambda

現状 CloudWatch Events Schedule によって1分間隔で起動させているLambdaを、10秒間隔、15秒間隔など秒単位で定期実行したい要件があり、実装方法を検討したのでその結果を残します。

Lambdaを定期的に起動するLambdaを導入してみた

1分毎に起動して、指定したLambdaを指定した間隔で起動し、1分後に終了するLambdaを作れば良いのでは、という案を思いつきました。 10秒間隔で Lambda を定期実行させる Lambda をNode.js v6.10 で素朴に作ってみました。

gist.github.com

funcName に1分間隔より短い間隔で定期実行させたいLambdaの名前を指定します。 このLambda を CloudWatch Events Schedule で1分間隔で定期実行させることで、このソースコードの例では10秒間隔で指定したLambdaを定期実行することができます。

注意点

  • funcName に指定した Lambda (10秒間隔で実行したいLambda)のトリガとしてCloudWatch Events Scheduleの定期実行設定が残っていると多重起動してしまうので、そちらのトリガは削除しておかないといけません
  • この「10秒間隔で Lambda を定期実行させる Lambda」に割り当てるIAMロールへは、InvokeするLambda(10秒間隔で実行したいLambda)に対して lambda:InvokeFunction Actionを実行できる権限を付与しておく必要があります
  • この「10秒間隔で Lambda を定期実行させる Lambda」のタイムアウト値は 60秒以上を設定する必要があります

...あれ?

できたはできたけど...

注意点の最後に挙げた項目が Lambda の、というかイベント駆動で動くFaaSの旨味を思いっきり消してしまっている気がします。 要するにこの「10秒間隔で Lambda を定期実行させる Lambda」は1分間起動し続けていなければならず、それもうEC2でも良くね?という気持ちが芽生えてきます。

実際にLambdaとEC2でそれぞれ1日中稼働させた場合のコストを比較すると、

Lambdaで運用

  • メモリ割当 128MB、1回あたりの課金時間を 61,000ms(61秒)とする
    • 実際には60,600ms くらいで終わることも多いのですが、ここでは多めに見積もります
  • 1日の実行回数は 1440回
    • 60(min) × 24(h)
    • 毎月最初の 1,000,000 回は無料、かつ、それ以上実行しても $0.0000002 /回 という安価さなので計算から除外する

料金 - AWS Lambda(サーバーレスでコードを実行)|AWS

$0.000000208(/100 ミリ秒) × 610(100ミリ秒/回) × 1440(回) =$0.1827072

EC2で運用

  • オンデマンド料金で算出する
  • インスタンスタイプは一番小さい t2.nano、台数は1台とする

オンデマンドインスタンスの料金 - Amazon EC2 (仮想サーバー) | AWS

  • 東京リージョンの場合

$0.0076(/1h) × 24(h) = $0.1824

$ 0.0058(/1h) × 24(h) = $0.1392

結論

費用面だけ見ると、EC2(t2.nano)を常時起動していても対して変わらない、むしろ安い場合もある。という結果になりました。 しかし、EC2上で秒単位で起動するworkerを動かす場合と比較して、Lambdaで実行するのには以下のメリットがありそうです。

  • 実装が簡単
  • コケても次回(1分後)の実行に影響が出ないので一度軌道に乗れば運用は楽
  • そもそもLambdaの実行のためにEC2を動かすのはなんかスッキリしない

逆に、何らかの用途ですでに常時起動しているEC2がいる場合はコストを考えて秒単位で起動するworkerを相乗りするのも手ですね。

・・・ひどく当たり前の結論になってしまいました。
秒単位でLambdaを定期実行したいときって、どうするのがスマートなのでしょうね??