【AWS】起動方法から考えるStep Functionsでの定期ジョブシステム
概要
AWS の Step Functions といえば簡易に順序だった複数タスクを実行するワークフローを実装できるサービスです。
Amazon States Language という JSON ベースの言語によるワークフローの定義と出来上がるワークフローの抽象化された見た目により実装自体は簡単ですが、起動方法やタスク間でのデータ管理、フロー設計等悩むポイントも度々発生するというのが所感です。
特に最初につまずくポイントとしてワークフローを組む際に起動をどのように行うかということがあります。
定期的にワークフローを実行するにはどの様にワークフローを起動するのか、大規模なジョブシステムを組む際にはどの様に複数ワークフローを連携して起動させていくのか、AWS 外のサービスからワークフローを起動するにはどのように起動するのか等、起動方法について考える点はいくつか挙げられます。
そこで、今回は一般的なシステムで実装される定期ジョブシステムを前提とし、 Step Functions のワークフローの起動方法からどの様なワークフローが組まれることが想定されるのか、またそのワークフローはどういった規模の定期ジョブシステムに適しているのかということを考えてみます。
StepFunctions のワークフローの起動方法や各起動方法から組まれるワークフローの例を知っておきたい方の助けになれば幸いです 🙏
起動方法について
まずワークフローの起動方法についてです。
起動方法についてですが、定期ジョブシステムを実行する際に考えられる物として主に下の三つが考えられます。
- EventBridge Scheduler から起動する
- ワークフロー内のタスクから起動する
- AWS CLI や API Gateway を使用して外部サービスから起動する
各起動方法から実際に実装される Step Functions のワークフローを考えてみます。
EventBridge Scheduler から起動する
EventBridge Scheduler から起動するですが、Step Functions で定期ジョブを実行することを考えると多くの方がこの方法を取ることになると思います。
AWS 公式の開発ドキュメントでも起動方法の例示として挙げられていますし、以下の様に cron 式での定時でのワークフローの起動設定も簡単だからです。
cron([分], [時間], [日付], [月], [曜日], [年])
cron 式は上記の様に設定でき、カンマ区切りで指定された箇所の引数として数字やワイルドカードを指定することで柔軟な定時表現をすることができます。
また、注意点として設定した時刻は UTC 時刻で認識されるため設定したい日本時刻の 9 時間前で cron 式を設定しなければならないということがあります。
例えばcron(0, 15, *, *, ?, *)
で毎日 0 時実行、cron(0, 3, L, *, ?, *)
で毎月最終日 12 時実行等です。
上記 cron 式は便利ではあるのですが表現しづらい時間も存在します。
例えば祝日や毎月最終日の 0 時等です。
また、運用者がカレンダー上で指定したバラバラの日付の日だけ定期ジョブを実行したいという場面もあります。
こういった場合便利なのが Systems Manager Change Calendar です。
上記の様に GUI 上でカレンダーにジョブを実行する時間帯を簡単に設定することができ、Step Functions の Systems Manager Change Calender の Get Calender State というタスクでワークフロー実行日がカレンダーに設定されているか判断したのち、実行日である場合実行する、そうでない場合実行しないという実装を簡単に行うことができます。
これで cron で簡単に時間を表現できない変則的な時間を表現することができますし、運用者にとってもジョブ実行する日を GUI 上で簡単に設定できることになります。
まとめ
上記をまとめると、基本的に定期ジョブシステムを起動する際、EventBridge Scheduler で時間指定を行いつつワークフローを起動するには以下の様な方法が取られることになると思います。
- cron 式で対応できる範囲のシンプルな時間指定は cron 式で行う
- cron で簡単に時間を表現できない変則的な時間の表現は Systems Manager Change Calender で行う
ワークフロー内のタスクから起動する
ワークフロー内のタスクから起動するですが、定期ジョブシステムを組む際に、連携したジョブの実装が求められますのでそこで使用されることになります。
例えば、0 時に購入履歴の合算ジョブ → 終了後売却履歴の合算ジョブ → 終了後購入・売却履歴の合算ジョブといった連携したジョブを Step Functions で実装する場合、特に何も考えずに組むとジョブごとに独立したワークフローが三つ組まれることになります。
ジョブ連携の流れとしては、EventBridge Scheduler で 0 時に購入履歴の合算ジョブを行うワークフローを起動し、ジョブ終了後ワークフロー内から AWS Step Functions の Start Execution タスクを使用して売却履歴の合算ジョブを起動、その後同じ様にジョブ終了後ワークフロー内から AWS Step Functions の Start Execution タスクを使用して売却履歴の合算ジョブを起動という流れになります。
上記の場合ワークフロー内部の処理実行の流れは俯瞰して見ることができますが、独立したワークフロー同士の連携の流れは俯瞰して見ることができません。
Step Functions で俯瞰して見ることができるのはワークフローのフローのみだからです。
上記の様にジョブを複数ワークフローに分けず、全てのジョブを一つのワークフローにまとめればいいのでは?という意見もあるかもしれないですが、その場合一つのワークフローがファットになりすぎてしまいワークフローを追うのが大変になってしまう、メンテナンスもしづらくなってしまうという懸念点があります。
また、上記 3 つ程度のジョブの連携を 3 つのワークフローで行う程度なら Step Functions でも扱えるかもしれませんが 10 個のジョブを 10 個のワークフローで連携するとなると更に複雑なワークフローの管理が求められてきます。
そこで考えられるのが複数のワークフローを一つのメインワークフローで管理することです。
下記の様にワークフロー内で別々のジョブを実行すればジョブを俯瞰して見ることができ、失敗したジョブがどれか等もすぐに分かります。
まとめ
上記をまとめると、ワークフロー内のタスクから別ワークフローを起動することで定期ジョブシステムを連携して起動することを考えた時、以下の様な方法が取られることになると思います。
- 複雑すぎない 2、3 個程度のワークフローの連携はメインワークフローを実装せずに行う
- 連携するワークフローの数が増え、管理が複雑になってきたらメインワークフローを作成し俯瞰して管理を行えるようにする
AWS CLI や API Gateway を使用して外部サービスから起動する
AWS CLI や API Gateway を使用して外部サービスから起動するですが、Systemwalker Operation Manager、JP1 等のジョブ管理システムによるジョブ管理を行うケースで使用されることになると思います。
前章で述べた Step Functions 内でのジョブ管理ですが、Systemwalker Operation Manager、JP1 等のジョブ管理システムというジョブ管理に特化したシステムがあるためこちらを使用すれば簡単に実装できることになります。
大規模サービスにおいてはジョブが次々追加されたり管理が複雑になるということは往々にしてあることなので、最初からこちらを使用したほうがよいかもしれません。
ジョブ管理システム でジョブ管理を行う場合、メインのジョブ管理は ジョブ管理システム で行い一部ジョブを Step Functions のワークフローで行いたいといった場合に AWS CLI や API Gateway が使用できるといった使い方になると思います。
では具体的にその様な状況を考えてみると、Step Functions で組まれた既存ジョブをジョブ管理システムから実行したい時等が考えられます。
もともと作成していた Step Functions ワークフローを定期ジョブにしたくなった、別チームが開発している Step Functions ワークフローも定期ジョブにしたくなったということは起こり得ます。
このワークフローの起動の際に AWS CLI や API Gateway を ジョブ管理システム から利用することになります。
まとめ
上記をまとめると、ジョブ管理システムからワークフローを起動することを考えた時、以下の様な方法が取られることになると思います。
- 大規模サービスにおいてジョブ管理を行いたい場合、基本的にはジョブ管理システムを利用する
- 一部ジョブのみ Step Functions を用いて処理実行したい場合、AWS CLI や API Gateway を通して Step Functions を実行する
まとめ
上記定期ジョブシステムを前提とし、各起動方法から組まれるワークフローをまとめると、下記の様な結論が得られます。
- AWS サービスを利用して軽めの定期ジョブシステムを組みたい場合
- EventBridge Scheduler + Step Functions で実装、ジョブ連携の際はワークフロー内のタスクから別ワークフローを呼び出す
- AWS サービスのみを使用して大規模定期ジョブシステムを組みたい場合
- EventBridge Scheduler + Systems Manager Change Calender + Step Functions で実装されたジョブ管理を行うメインワークフローと実際のジョブが実行される子ワークフローを組み合わせてジョブ連携を実装
- ジョブ管理システムを使用して大規模定期ジョブシステムを組みたい場合
- ジョブ管理は 基本ジョブ管理システム で行い、一部 取り込みたくなった Step Functions ジョブのみ AWS CLI、API Gateway 等で定期ジョブとして取り込む
基本個人開発等複雑なジョブ管理が必要にならず、管理するジョブが 2、3 程度のシステムなら 1 の様に EventBridge Scheduler + Step Functions で単独ワークフローを複数実装するで良いと思います。
ただ、管理するジョブが 10、20 と複数必要であるかつシビアな運用を行うという話になってきた時はジョブ管理を行うことが求められてきます。
そうなった際にはジョブ管理をするワークフローが求められますので、2 の様に Step Functions でワークフローを作成するか 3 の様にジョブ管理システムを使用するかした方が良いということになります。
ではどちらの実装方法で管理するのかというと要件によって異なるというのが結論になります。
AWSネイティブなサービスのみでシステムを組むといった要件がある場合 2 の方法を取ることになります。
メリットとして AWS ネイティブなサービスのみでのジョブシステム構築が可能なので、余計に外部システムを導入する必要がなくなりメンテナンスコストが下がる、Step Functions のワークフローは実行時間ごとに費用を払う従量課金サービスのためコストが浮くといったことになります。
しかし、デメリットとしてメインワークフローのメンテナンスの必要性やもともとジョブ管理システムとして作成されたサービスではないため日付指定処理等ジョブ管理システムなら自身で持っている機能を自前で実装しなくてはならないということがあります。
AWS ネイティブなサービスのみでシステムを組むといった要件がない場合、3 の様に ジョブ管理システムでジョブ管理を行うといったことが妥当になると思います。
メリットとしてジョブ管理を行うためのワークフローのメンテナンスをせずに済む、ジョブ管理に特化したサービスであるため日付指定処理等を自前で実装しなくても良いということがあります。
デメリットとして、AWS ネイティブなサービスでジョブシステムを組めなくなる、導入コストが高く個人では導入し辛いということがあります。
ただ、やはり大規模なジョブ管理を行うという前提に立った時は ジョブ管理システムでのジョブ管理が必要になってくるというのが所感ではあります。
終わりに
今回は、Step Functions の起動方法を起点にどのように定期ジョブシステムを組むかについて考えてみました。
定期ジョブシステム、どの様な会社でも実装する物なので様々な会社の資料を見る機会になって良かったです。
規模や要件によって組み方は変わってくるし、他にも様々な実装方法で定期ジョブシステムを Step Functions で実装することもあると思います。
ここまでお読みいただきありがとうございました 🙇♀️
参照
Discussion