【Airflow】DAG実行タイミングを改めて纏めてみた


はじめに

こんにちは。ジールの@________________-_です。

DAG実行タイミングのクセがスゴイんじゃ

すいません。これが言いたかっただけです。
DAG実行タイミングをわかったつもりになっていたのですが、
改めてちゃんと理解しようと思い自分用にまとめました。

結論

DAG初回実行タイミングは、start_date以降直近のschedule_interval完了時点となる。
それ以降はschedule_intervalが完了する毎に実行される。
これだけだと全くわからないな。。。

詳細

DAG実行タイミングはstart_dateschedule_intervalを利用して計算される。

  • start_date:DAG実行タイミングを計算するための基準となる時間
    • start_dateとschedule_intervalを組み合わせて初回実行タイミングが計算される
  • schedule_interval:実行間隔
    • 単純にそのタイミングが来たら実行ではないのでややこしい。。。
    • 主にcron式で実行間隔を定義する

例えばstart_date:2021-2-17 10:00:00 --- schedule_interval:0 11 * * *だったとき、
直感的に初回タイミングは2021-2-17 11:00:00であるが、待てどもDAGが実行されることはない。
初回実行されるのは2021-2-18 11:00:00(翌日の11時)である。

どういうことかと言うと、Airflowではintervalの開始ではなく完了時にDAGが実行される仕組みとなっている。
schedule_interval0 11 * * *は毎日11時の設定なので、intervalの間隔は当日11時~翌日11時までとなる。
2021-2-17 11:00:00は(初回DAG実行タイミングではなく)intervalの開始時間となり、intervalの完了である2021-2-18 11:00:00にDAGが実行される。
⇒恐らくここが一番ややこしい(クセがスゴイ)ポイントだと思う。

schedule_intervalは実行開始時間というよりも、intervalという名前どおり間隔と考えた方が分かりやすい。
実行開始時間が点だとすると、schedule_intervalは点ではなく線(intervalの開始と完了を結ぶ線)と捉えた方ががしっくりくる。
そして、繰り返しになるがDAG実行タイミングはschedule_intervalの完了時点となる。
なぜschedule_intervalの開始と完了をしつこく繰り返すかというと、AirflowのwebUI表示もこれまた分かりにくいからだ。

Airflowの表示を確認してみる。
条件は以下の通り。

  • airflow Ver:v2.3.0 airflow breezeを利用
  • start_date:2022-2-21 8:00:00
  • schedule_interval:12 9 * * *
  • 初回実行済の状態

まずはDAG一覧表示を確認する。

注目点はLast RunNext Runである。
Last Runという記載だが実際DAGが実行されたタイミングではない。
これは、前回のschedule_intervalの開始時間である。実際実行されたのはschedule_interval完了時点なので2022-2-22 9:12:00である。
また、Next Runも同様次回実行タイミングではない。こちらも次回のschedule_intervalの開始時間である。次回が実行される(予定)のは2022-2-23 9:12:00となる。
どちらも表記もintervalの開始を意味しており、実際のDAG実行時間ではない。

次に対象のDAGの実行リストを確認する。

こちらの注目点はLogical DateStart DateEnd Dateである。
※時間表記がUTCとなっているので注意

Logical Dateは、DAG一覧表示のLast Runと同じ時間である。つまり、これはschedule_intervalの開始時間は意味している。
※以前はExecution Dateという名称だったため更に分かりにくかった。。。Logical Dateに名称変更されて感謝しかない。

Start Date・End Dateは本当のDAG実行時間となる。schedule_intervalが完了して実行された具体的な時間だ。
Logical Dateと比較すると丁度1日ずれているのが分かると思う。schedule_intervalは日次実行で設定している為、
schedule_intervalの完了後(1日後)に丁度実行されているのが確認できる。

改めてDAG実行のタイミングは以下となる。

  • start_dateから直近のschedule_intervalが初回interval開始時間(=初回Logical Date)
  • 初回intervalの完了時間が初回DAG実行タイミング
  • 初回intervalの完了時間は2回目のinterval開始時間(=2回目のLogical Date)
  • 2回目のinterval完了時間が2回目のDAG実行タイミング
  • 後はこれの繰り返し

  • start_date:2021-2-17 10:00:00 -- schedule_interval:0 11 * * *の場合

    • interval開始時間:2021-2-17 11:00:00
    • 初回DAG実行タイミング:2021-2-18 11:00:00
    • start_dateが10時でintervalが毎日11時なので、10時以降で直近の11時がinterval開始時間の2021-2-17 11:00:00。intervalは11時から翌日の11時までなので、interval完了タイミングとなる翌日11時の2021-2-18 11:00:00がDAG実行タイミングとなる。
  • start_date:2021-2-17 10:00:00 -- schedule_interval:0 9 * * *の場合

    • interval開始時間:2021-2-18 9:00:00
    • 初回DAG実行タイミング:2021-2-19 9:00:00
    • start_dateが10時でintervalが毎日9時なので、10時以降で直近の9時がinterval開始時間となる。start_dateは10時で9時よりも遅い時間の為2021-2-17にinterval開始は不可能となる(21日の9時は過ぎている為)。結果、翌日の2021-2-18 9:00:00がinterval開始時間となる。intervalは9時から翌日の9時までなので、interval完了タイミングとなる翌日9時の2021-2-19 9:00:00がDAG実行タイミングとなる。

catchupの利用

airflowのcatchupとは、DAGを新しくデプロイした際に過去分の実行が出来る機能のことだ。
catchup=Trueとすることで、過去のDAGが実行される。
具体的には、start_dateから現在(=DAGをデプロイしてAirflowがDAGを認識したタイミング。正確には違うのかもしれないが一旦そういうていで進める)までのinterval完了分のDAGが順次実行される。
例えば、

  • start_date:2021-2-16 10:00:00
  • schedule_interval:0 10 * * *
  • 現在(デプロイ時間):2021-2-18 11:00:00

の場合、
start_dateから計算して完了しているintervalは2月16日10時~2月17日10時、2月17日10時~2月18日10時の2回となる。
この過去分2回が自動的に実行される。
2月18日10時~2月19日10時のintervalは、現在が2月18日11時なのでintervalが完了しておらず対象とはならない。
2月19日10時になった時点で(過去分実行ではなく)通常実行される。

では、catchup=Falseの場合はどうなるのか。
結論としては2月17日10時~2月18日10時の1回が過去分として実行される。
catchup=Falseは過去分を全く実行しないのではなく、現在(デプロイ時間)での最新のinterval完了分のみ実行する。

catchupを全く実行したくない場合はというと、start_dateを上手く調整して現在(デプロイ時間)時点でintervalが完了しないようにすればよい。
例えば、

  • start_date:2021-2-18 10:00:00
  • schedule_interval:0 10 * * *
  • 現在(デプロイ時間):2021-2-18 11:00:00

とすることで、初回のinterval期間が2月18日10時~2月19日10時となる。
現在(デプロイ時間)時点でintervalが1つも完了していないので過去分を一切実行されない(実行される過去分が存在しない)。
この時初回実行タイミングは2月19日10時となる。

改めてまとめ

start_dateとschedule_intervalから初回実行タイミングが計算される。
初回実行以降はschedule_intervalが完了した毎に実行される。

  • start_date:DAG実行タイミングを計算するための基準となる時間
  • schedule_interval:実行間隔(単純な実行タイミングではないので注意)
  • 初回interval開始時間:start_date以降で直近のschedule_interval時間
  • 初回interval完了時間:初回schedule_intervalが完了する時間(=次回のschedule_interval開始時間)
  • 初回実行タイミング:若干のずれはあるが初回intervalが完了したタイミング
  • 初回以降の実行タイミング:初回interval完了時間からschedule_intervalが完了する毎に実行タイミングがくる

おわりに

慣れると不思議と違和感が無くなっていきますが、初見の時はん???と思うのではないでしょうか。
UIの表示も上記を理解していないと。。。ですし。
ただ、Airflow自体は(色々と癖が強いですが)とても良いサービスだと思います。
google cloud・AWSともにAirflowをホストしたサービスが展開されてますし、更に広がっていくと嬉しいです!

参照

個人的にはcloud composerの公式ページの説明が分かりやすいと思いました。