今さら聞けないTreasure Workflow


始めに

本記事ではTreasure Workflow(以後Workflow)における用語について説明します。
なんとなく使っていたけどよくわかっていない人や、使っていて何がなんだかわからなくなった人は読んでいただけますと幸いです。

Workflow と Digdagって何が違うの?

本題に入る前に、WorkflowとDigdagの違いについて簡単に説明します。

DigdagはOSSのワークフローエンジンです。動作環境は自前で用意する必要があり、当然自分たちで運用しなければいけません。代わりに設定は自由にできますし、任意のタイミングでメンテナンス・バージョンアップなども可能です。

Workflowは簡単に言ってしまえばDigdagをTreasure Data(以下TD)がホストしているサービスです。作成したworkflowはTreasure Dataが運用しているサーバー上で動作するため、OSリソースなどは意識する必要がありません。代わりに無茶な使い方ができないように制限を設けています。

そのため、極論ですがDigdagとWorkflowは同じと言えなくもないです。

Workflow の用語

では本題に入ります。
Workflowに関連するコマンドのヘルプを見てみましょう。

$ td wf --help
2019-12-06 21:18:38 +0900: Digdag v0.9.39
Usage: td workflow <command> [options...]
  Local-mode commands:
    init <dir>                         create a new workflow project
    r[un] <workflow.dig>               run a workflow
    c[heck]                            show workflow definitions
    sched[uler]                        run a scheduler server
    migrate (run|check)                migrate database
    selfupdate                         update cli to the latest version

  Server-mode commands:
    server                             start server

  Client-mode commands:
    push <project-name>                create and upload a new revision
    download <project-name>            pull an uploaded revision
    start <project-name> <name>        start a new session attempt of a workflow
    retry <attempt-id>                 retry a session
    kill <attempt-id>                  kill a running session attempt
・
・

無邪気にWorkflowを使おうとした人からすると、projectとかsessionとかあるけど何なの?となってしまうかと思います。
なので今さらかもしれませんがそれぞれ説明していこうかと思います。

ProjectとWorkflow

TDコンソール(ブラウザ)で新規Workflowを作成しようとすると下記画面に遭遇します。

Workflow NameとProject Nameを入力する必要があるみたいだけどそれって何なの?となりますよね。

Projectとは、ファイルを入れるディレクトリ、フォルダです。
Workflowとは、フローを書いたdigファイルのことを指します。

下記ディレクトリ構造では、test_prj1がProjectです。
test_main.digtest_sub.digがWorkflowです。

$ tree test_prj1
test_prj1
├── load1.yml
├── load2.yml
├── sample1.sql
├── sample2.sql
├── test_main.dig <-- workflow
└── test_sub.dig <-- workflow

Projectはただの入れ物なので、1つのProjectに複数のWorkflowを配置したり、SQLファイルやymlファイルを配置してWorkflowから呼び出したりすることが可能です。

勘がいい人は気づいたかと思いますが、Projectが違えば同じ名前のWorkflowを作成することができます。そのため、作業する際はどのProjectにあるWorkflowなのかを意識するようにしてください。
test_main.digを修正しているつもりがtest_prj2というProjectのtest_main.digを修正している、なんてことがあり得ます。

Session と Attempt

Workflowの過去実行履歴を確認しようとすると下記画面に遭遇します。

SessionとかLast Attemptって何?ってなりますよね。

Workflowとはその名の通り決まった一連の処理を定義し実行するためのサービスです。日次で実行させることが多々あるのですが、当然重複して実行されると困ってしまいますよね。
そういったことがないように予定を定義し実行済みかどうかWorkflowは認識しておく必要があり、その予定をSessionと呼びます。
日次のWorkflowで言えば、12/01のSession、12/02のSessionというようなイメージです。

一方、Attemptは予定ではなく実際に実行されたSessionを意味しています。
実行済みの日次のWorkflowでは、各日のSession(予定)に対してそれぞれAttemptが存在しています。

12/01のSession --> 12/01のSessionのAttempt
12/02のSession --> 12/02のSessionのAttempt
・
・

ここまでの説明だけでは「Attemptって必要なの?」と思うかもしれませんが、Attemptは失敗したときの制御を考えると必要な要素なのです。
ネットワークの瞬断のような障害や、クエリで利用するテーブルが存在していなかったというようなオペレーションミス・考慮漏れが原因でWorkflowが失敗してしまうことが考えられます。業務上必要な処理であればリトライしてリカバリする必要があります。
Workflowからすると「失敗したときの実行」と「成功時の実行」を区別する必要があり、それぞれ別のAttemptとして扱うことで制御しています。

そのためSessionとAttemptは1対Nの関係となります。エラー原因が解消できていないのにリトライし続けるとその分Attemptが増えていきますし、全てのSessionが成功している場合は1対1対応になります。

そしてSessionとAttemptには内部的にIDが付与されています。これらは全Workflowで一意の値になるため、Workflowが失敗したときにはAttempt IDで区別すると取り違えるということがなくなります。

下記例で言えば、1つのSession(ID: 15750257)に対して2つのAttempt(ID: 69567517, 69567483)が存在しています。

Revisionとは

ProjectのバージョンのことをRevisionと呼びます。Workflow(digファイル)のバージョンではなくProjectのバージョンなので、特定のWorkflowのみ戻すというような細やかなバージョン管理はできません。
もし間違ってファイルを編集・保存してしまったときは、下記コマンドで任意のRevisionのProjectを手元にダウンロードすることができるので、それを元に復旧させるといったことが可能です。

$ td wf download --help
2019-12-06 22:13:36 +0900: Digdag v0.9.39
Usage: td workflow download <project>
  Options:
    -r, --revision REVISION          specific revision name instead of the latest revision

TDコンソール上ではProjectのロールバックをすることができないので改善ポイントですね!

最後に

本記事を読んで、ざっくりとでもWorkflowの概念について理解してもらえると嬉しいです。もしわからなくなったらTreasure Dataに問い合わせると教えてくれると思います!