第4章 Lakeflow Jobsによるオーケストレーション / 想定学習時間:30〜40分 / 最終確認:2026年8月

4-2. 制御フロー(リトライ・条件分岐・ループ)

🎯 この節の学習目標

1. なぜ制御フローが必要か

4-1 で学んだ DAG は「タスクを決まった順序で流す」仕組みでした。しかし実運用のパイプラインでは、「一時的なエラーならもう一度試したい」「データの有無で処理を切り替えたい」「同じ処理を複数の対象に繰り返したい」といった要求が必ず出てきます。Lakeflow Jobs はこれらをリトライ・条件分岐(If/else、Run if)・ループ(For each)という制御フロー機能で解決します。ノートブックの中に if 文や for 文を書き込むのではなく、ジョブの構造として制御を表現することで、実行状況の可視化・部分的な再実行・並列化が容易になります。

2. リトライ:一時的な失敗への備え

タスクにはタスクレベルのリトライを設定できます。ネットワークの瞬断、外部APIの一時的な過負荷、クラウドストレージの一時エラーなど、「時間をおいて再実行すれば成功する」タイプの失敗(一過性障害)に有効です。

設定項目内容
最大リトライ回数失敗時に何回まで再試行するか(無制限も指定可能)
リトライ間隔再試行までの待ち時間。外部システムの回復を待つ余裕を持たせる
タイムアウトタスクの最大実行時間。ハングした処理を打ち切る保険として併用する
通知失敗・成功・開始などのイベントをメールや連携先(Slack、Webhook 等)に通知する。ジョブ単位・タスク単位で設定可能

📝 試験のポイント

「外部システムが時々一時的なエラーを返し、そのたびにジョブ全体が失敗して担当者が手動再実行している。運用負荷を下げるには?」→ 正解の軸は「該当タスクにリトライ(回数と間隔)を設定する」です。「ジョブ全体を二重にスケジュールする」「失敗を無視する」といった選択肢は誤答です。また、リトライはコードのバグによる恒常的な失敗は解決しない点も押さえましょう。何回再実行しても同じバグでは失敗します。

3. 条件分岐:If/else condition タスクと Run if

Lakeflow Jobs の条件分岐には、性格の異なる2つの仕組みがあります。「値」で分岐するのが If/else condition タスク、「依存タスクの成否」で実行可否を決めるのが Run if 条件です。

3-1. If/else condition タスク:値にもとづく分岐

If/else condition タスクは、それ自体が1つのタスクタイプで、指定した条件式の真偽を評価します。条件には、ジョブパラメータや、前段タスクがセットした task values(4-1)を使えます。条件式の結果に応じて、後続タスクを「true 側の枝」と「false 側の枝」に振り分けます。

💡 具体例:新着データの有無で処理を切り替える

前段の取り込みタスクが、処理した件数を task value(例:new_records)にセットします。続く If/else condition タスクで「new_records > 0」を評価し、true なら変換タスクへ、false なら変換をスキップして「新着なし」の記録タスクへ進めます。データがない日に重い変換処理を空回りさせない、という無駄の排除がノートブックのコードではなくジョブの構造として表現でき、実行履歴の画面でもどちらの枝に進んだかが一目でわかります。

3-2. Run if:依存タスクの成否による実行条件

Run if は独立したタスクタイプではなく、各タスクが持つ実行条件の設定です。既定では「依存先タスクがすべて成功したら実行(All succeeded)」ですが、これを変更できます。主な条件は次のとおりです。

Run if 条件実行されるタイミング典型的な用途
All succeeded(既定)依存先がすべて成功したとき通常の後続処理
At least one succeeded依存先の少なくとも1つが成功したとき複数ソースのうち一部でも取り込めたら集計を進める
None failed失敗した依存先がないとき(スキップは許容)スキップされた枝があっても続行したい処理
All done成否を問わず依存先がすべて終了したとき一時リソースの後片付け、実行結果の記録
At least one failed依存先の少なくとも1つが失敗したとき失敗時の後始末や詳細なエラーレポート作成
All failed依存先がすべて失敗したとき全滅時のみ発動させる代替処理

📝 試験のポイント

両者の使い分けは「何を条件にするか」で判断します。データの値・パラメータ・task value で分岐したいなら If/else condition タスク、前段タスクの成功/失敗という実行結果で動かしたいなら Run if です。たとえば「上流タスクが失敗したときだけクリーンアップ処理を動かしたい」は Run if(At least one failed)、「取り込み件数が0なら後続をスキップしたい」は If/else condition が正解の軸になります。

4. ループ:For each タスク

For each タスクは、入力値のリスト(配列)に対して、ネストしたタスクを繰り返し実行する仕組みです。入力にはジョブパラメータや task value の配列(例:["tenant_a", "tenant_b", "tenant_c"])を指定でき、各要素の値が繰り返しごとのパラメータとして渡されます。

💡 具体例:複数テナントの日次集計

あるSaaS企業のデータチームが、30テナント分の利用ログを同じロジックで日次集計するとします。テナントごとに30個のタスクを手作業で複製するのは保守が困難です。代わりに、テナントIDの配列を入力とする For each タスクの中に集計ノートブックタスクを1つ置き、並列度を例えば5に設定します。テナントが増えても入力配列に追加するだけで済み、特定テナントの失敗時はその繰り返しだけを再実行できます。

5. どの制御をどの要件で使うか

3つの制御フローは「困りごとの種類」に対応しています。試験でもシナリオから適切な制御を選ばせる形式が想定されるため、対応関係を整理しておきましょう。

要件・状況使う制御理由
外部APIやストレージがときどき一時的に失敗するリトライ(回数・間隔)時間をおけば成功する一過性障害には再試行が最も単純で効果的
データの有無や値に応じて処理を切り替えたいIf/else condition タスクtask value やパラメータの条件式で true/false の枝に分岐できる
前段の失敗時だけ後始末・通知処理を動かしたいRun if(At least one failed 等)依存タスクの成否そのものを実行条件にできる
複数テナント・複数地域に同じ処理を繰り返したいFor each タスク(+並列度)配列の各要素をパラメータに同型処理を並列実行できる

✅ この節のまとめ

練習問題

問1. 夜間ジョブの取り込みタスクが、外部ストレージの一時的なエラーで月に数回失敗し、担当者が翌朝手動で再実行している。運用負荷を減らす最も適切な対策はどれか。

  1. タスクに最大リトライ回数とリトライ間隔を設定し、失敗が続いた場合の通知を構成する
  2. 同じジョブを1時間ずらして二重にスケジュールする
  3. 取り込みコードの try/except でエラーを握りつぶし、常に成功として扱う
  4. ジョブを廃止して手動実行に一本化する
解答と解説を見る

正解:A

一時的なエラーはリトライで自動回復させるのが定石で、それでも失敗する場合に備えて通知を設定します。Bは成功時に同じ処理が二重実行される危険があり、根本対策になりません。Cはエラーの隠蔽であり、データ欠損に気づけなくなります。Dは自動化を放棄しており、運用負荷はむしろ増えます。

問2. 前段の取り込みタスクが task value に新着件数をセットする。「新着が1件以上なら変換タスクを実行し、0件なら変換をスキップする」を実現する最も適切な方法はどれか。

  1. 変換タスクの Run if を「At least one failed」に設定する
  2. If/else condition タスクで task value の件数を条件式で評価し、true 側に変換タスクを接続する
  3. 変換タスクに最大リトライ回数を設定する
  4. For each タスクで変換を繰り返し実行する
解答と解説を見る

正解:B

「値(件数)にもとづく分岐」は If/else condition タスクの役割で、条件には前段がセットした task value を使えます。Aの Run if は依存タスクの成否を条件にする仕組みで、件数のような値では判定できません。Cのリトライは失敗時の再試行であり分岐ではありません。Dのループは繰り返し実行の仕組みで、条件による切り替えには使えません。

問3. 並列に実行される3つの取り込みタスクのうち、どれか1つでも失敗した場合にのみ、エラー詳細をまとめて管理チームに報告するタスクを実行したい。最も適切な設定はどれか。

  1. 報告タスクの Run if を既定(All succeeded)のままにする
  2. 報告タスクを If/else condition タスクに置き換え、常に true になる条件を設定する
  3. 報告タスクを3つの取り込みタスクに依存させ、Run if を「At least one failed」に設定する
  4. 3つの取り込みタスクにリトライを無制限に設定し、報告タスクは作らない
解答と解説を見る

正解:C

「依存タスクの失敗を条件に実行する」は Run if の典型ユースケースで、「At least one failed」が要件どおりです。Aの既定(All succeeded)では全タスク成功時にしか実行されず、目的と正反対です。Bは成否ではなく値で分岐する仕組みのうえ、常に true では「失敗時のみ」を表現できません。Dの無制限リトライは恒常的な失敗で終わらないジョブを生み、報告の要件も満たしません。

問4. 40個の地域コードそれぞれに対して同一の集計ノートブックを実行したい。地域は今後も増える予定で、処理時間の短縮のため同時に数地域ずつ処理したい。最も適切な構成はどれか。

  1. 地域ごとに40個のノートブックタスクを手作業で作成し、直列につなぐ
  2. 地域コードの配列を入力とする For each タスクの中に集計タスクを置き、並列度を指定する
  3. If/else condition タスクを40段ネストして地域を切り替える
  4. 40個の別々のジョブを作成し、それぞれ別の時刻にスケジュールする
解答と解説を見る

正解:B

「同じ処理をパラメータ違いで繰り返す+並列度の制御」は For each タスクの設計目的そのものです。地域が増えても入力配列への追加だけで対応でき、失敗した地域のみの再実行もできます。Aは保守困難なうえ直列では時間もかかります。Cの If/else は分岐の仕組みであり繰り返しには不適です。Dはジョブが乱立して管理が破綻しやすく、依存関係や一括の成否管理もできません。