DynamoDBのTTL機能とLambdaを使ってサーバレスでのタイマー実行処理ができないか考えてみた

バッチ処理の中には、定期実行ではなく、特定の時刻に実行したい、みたいなものがあります。
例えば、今から5分後とか3日後の12:00とか。ジョブスケジューラでよくある感じのやつです。

AWSで、サーバレスなアーキテクチャ(実行基盤はAWS Lambda *1)でこの処理を実現する方法について考えました。

定期実行の場合

そもそも単純な定期実行の場合は、以下に書かれているように、CloudWatch Eventsを使うことで実現できます。

スケジュールされたイベントでの AWS Lambda の使用 - AWS Lambda

ただこの仕組みは「Rate または Cron を使用したスケジュール式 - AWS Lambda」で表現可能なスケジュール実行しかできないので、起動したい処理(タスク)がいっぱいあり、それらの指定開始時刻がバラバラな場合、使うのは難しそうです。

タイマー実行(スタンダード?な方法)

スタンダードなやり方だと、以下のどちらかでしょうか。

  • 処理タスクをキューに貯めて、定期的にポーリング
  • EC2などでQuartzのようなスケジューリング用のライブラリを使う

タイマー実行(DynamoDB)

今回考えた方法では、DynamoDBのTTL(Time to Live)機能を利用します。アイテムに設定された時刻(有効期限)になると、アイテムが削除されます。TTLを使った利用シーンとしては、キャッシュ、セッション管理、不要になった古いアイテムのパージなどですかね。

新機能 – TTL(Time to Live)機能を利用したDynamoDBアイテムの管理について | Amazon Web Services ブログ

重要なのは、TTLによってアイテムが削除された場合も、通常の追加・更新・削除と同様にDynamoDB Streamのトリガ(Stream)でイベントを発火させ、Lambdaで処理させることができる点です。

そのため、有効期限(TTL)として処理を開始したい時刻を設定することで、指定時刻でLambdaが実行できると考えました。

というわけで、簡単に試してみました。

で、結論ですが、「指定した時刻で」という条件を守るのは難しそうです。うーん、現実は厳しい。。
というのも、以下のドキュメントに書かれているとおり、DynamoDBの有効期限は、その時刻になったら削除されるというものではなく、ベストエフォートベース(具体的にいつ削除されるかは分からない)んですね。

docs.aws.amazon.com

今回は新規にテーブルを作って試したのですが、有効期限を00時26分35秒に作ったアイテムが実際に削除されたのは00時38分58秒(約12分後)でした。

Amazon Simple Workflow Service (SWF)

ここまで書いてAmazon Simple Workflow Service (SWF)の存在を思い出しました。
個人的にまだ使ったことはなく、名前にSimpleというワードを含んでいながらAWSの中でもトップクラスに複雑なサービスというイメージなんですが、どうなんだろう…。

*1:AWS Lambda単体で難しい場合、例えば、処理が複雑であったり、タイムアウトが起きるくらい実行時間がかかる場合は、AWS Step FunctionsやAWS Batchを使う(組み合わせる)イメージです。