バッチ処理の中には、定期実行ではなく、特定の時刻に実行したい、みたいなものがあります。
例えば、今から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の有効期限は、その時刻になったら削除されるというものではなく、ベストエフォートベース(具体的にいつ削除されるかは分からない)んですね。
今回は新規にテーブルを作って試したのですが、有効期限を00時26分35秒に作ったアイテムが実際に削除されたのは00時38分58秒(約12分後)でした。
Amazon Simple Workflow Service (SWF)
ここまで書いてAmazon Simple Workflow Service (SWF)の存在を思い出しました。
個人的にまだ使ったことはなく、名前にSimpleというワードを含んでいながらAWSの中でもトップクラスに複雑なサービスというイメージなんですが、どうなんだろう…。