この記事について

複数のGlue Job実行をワークフロー制御するためにGlue Workflowを利用していましたが、色々な理由がありワークフロー制御をStep Functionsに移行しました。
移行した経緯や理由、その際のポイントなどについて本記事で共有させていただきます。

移行の経緯

Glue Workflowの仕様による管理の煩雑化

プロジェクトにおいてGlue Jobを利用して、クラウドデータサービス(AWSのRDSやS3、Google CloudのBigQueryなど)間のETL処理を実装していました。そしてGlue Triggerで定期的にバッチ実行していました。
ある時、Glue Jobを単体だけでなく複数用いてワークフロー化したい要件が出てきました。そこで、Glue JobとGlue Workflowでワークフローを実装しました。

これを実装/運用していくにあたり、2つの問題が出てきました。

  • 1.Glue Workflow内のGlue Jobは全て一意である必要がある
  • 2.スケジュール毎にGlue Workflowを作成する必要がある

この2つの問題によりGlue JobとGlue Workflowを無駄に作成しなくてはならず、管理が煩雑になっていきました。

1.Glue Workflow内のGlue Jobは全て一意である必要がある

Glue Workflowでは同じGlue Jobを複数回使うことができません。もし同じGlue Jobを同一のWorkflowにて利用したい場合、同じ内容のGlue Jobを利用したい分作成する必要があります。
私のプロジェクトでは以下のようなGlue Jobを利用していました。

ポイントとしては

  • Glue Jobのスクリプトは全て同一の内容(共通スクリプトと呼んでいます)
  • Glue Jobの実行時に引数として呼び出したい個別モジュールを指定する

このように実装することで、コードを共通化して無駄を減らし、またGlue Jobも1つだけで済みます。(Glue Triggerはバッチ毎に作成する必要があります)

そしていざ複数のGlue Jobを含むGlue Workflowを実装しようとしたところ、1つのGlue Workflow内で同じGlue Jobを複数回利用できないという仕様が発覚しました。
仕方がないので、スクリプトと設定は同一で名前が異なるのGlue Jobを複数作成してGlue Workflowに組み込んでいましたが、Glue Workflowの数が増えるたびに無駄なGlue Jobが増えていくという事態になりました。

2.スケジュール毎にGlue Workflowを作成する必要がある

簡単に言うと、1つのワークフローをdailyとmonthlyなど2つのスケジュールで定期実行させたい時、Glue Workflowを2つ作成する必要があるということです。

Glue Workflowでは複数のGlue Job(とCrawler)を並列/直列に依存関係を持たせてワークフローとして定義して、実行することが可能です。しかし、その実態はGlue TriggerとGlue Jobの組み合わせにすぎません。
そして1つのGlue Workflowを実行するGlue Triggerは1つしか関連付けることができません。つまり同じGlue Workflowに2つ以上のGlue Triggerを関連付けすることができないのです。

上記の仕様により、「毎日AM4:00と毎月1日のAM6:00に実行」という要件を満たすためには、同じGlue Workflowを2つ作成する必要が出てきました。

Step Functionsで解決

先ほど説明したように、Glue Workflowでは以下の問題がありました。

  • 同じGlue Jobを1つのGlue Workflow内で複数利用することができない
  • 1つのGlue Workflowに紐づけられるTriggerは1つだけ

これをStep Functionsに移行することで、解決することができました。

構成としてはStep Functionsのステートマシンに必要なGlue Jobを組み込む、EventBridge Schedulerでスケジューリングするだけです。

Step Functionsは1つのステートマシン内で同一のGlue Jobを何度でも利用することが可能です。また1つのステートマシンに複数のEventBridge Schedulerを紐づけることが可能です。

さらにStep Functionsを利用することで、以下のメリットもあります。

  • 柔軟なワークフロー制御が可能
  • ワークフロー内の入力と出力の受け渡しが簡単に
  • AWSの他のサービスとの連携が可能

これらにより将来的により応用的で複雑なETL処理も実現することが可能になりそうです。

ただ2つだけStep Functionsに移行したことで、生じた問題もあります。

  • 学習コスト
  • オプショナルな引数を定義できない

学習コスト

Step Functionsは入力や出力の制御など少しクセがあります。そのため一定の学習コストは発生します。
ただ局所的にクセがある程度なので、そこまで学習コストが高いというわけではないと思います。(私は3日間ほど使えば慣れました)

オプショナルな引数を定義できない

Step Functionsでは1つのGlue Jobにて受け取る入力を以下のように定義します。

{
"JobName.$": "$.JobName",
"Arguments": {
    "--target.$": "$.target",
    "--param1.$": "$.param1",
    "--param2.$": "$.param2",
    }
}

ここで定義した値は全てステートマシン内のGlue Jobを実行する際に渡される必要があります。
Glue Jobのスクリプトにてオプショナルな引数を利用していましたが、この仕組みによりオプショナルな引数を定義することができなくなりました。(ステートマシンを工夫すればオプショナルな引数を設けられそうでしたが、構成が複雑になるため見送りました)

これにより、スクリプトの内容を修正してオプショナルな引数を利用しないような実装に修正する必要がありました。

料金

ついでに料金についても触れておきます。

Glue Workflowsは無料で利用可能です。
Step Functionsはワークフロー内に実行される処理(ステート)毎に料金がかかりますが、よほど大規模なワークフローじゃないと料金は微々たるものです。(実行頻度にも依りますが)
そのため、料金面ではGlue WorkflowsもStep Functionsも大差はないと考えています。

Glue WorkflowとStep Functionsの使い分け

基本的にStep Functionsを利用しておくで間違いないかと思います。ただし、「学習コストをかけたくない」かつ「ワークフロー構成がシンプル」であればGlue Workflowを利用するのもアリかなと思います。

まとめ

Glue Workflowには以下の仕様がある

  • 同じGlue Jobを1つのGlue Workflow内で複数利用することができない
  • 1つのGlue Workflowに紐づけられるTriggerは1つだけ

またそれ以外にもStep Functionsに比べて、以下の弱点がある

  • 柔軟なワークフロー制御ができない
  • ワークフロー内の入力と出力の受け渡しが大変
  • AWSの他のサービスとの連携が難しい

基本的にStep Functionsを利用しておけば良いが、以下の点は注意が必要

  • 学習コストが必要
  • オプショナルな引数を定義できない

みなさん、Step Functionsを使いましょう。