Зависимости задач: оператор сдвига
Урок учит выстраивать порядок выполнения задач в DAG.
Оператор сдвига (битовый сдвиг, два знака «больше») в Airflow задаёт зависимость:
a >> bозначает «сначала a, потом b».
Стрелки между задачами
Порядок задач в Airflow описывают перегруженными операторами. Запись extract >> transform читается как «extract предшествует transform». Стрелку можно развернуть: transform << extract означает то же самое. Эти стрелки и есть рёбра графа DAG.
a >> b # a, затем b
a >> b >> c # цепочка a → b → c
a >> [b, c] # a, затем b и c параллельно (fan-out)
[b, c] >> d # d ждёт и b, и c (fan-in)Параллелизм: fan-out и fan-in
Часто после одного шага можно запустить несколько независимых задач параллельно (fan-out), а потом собрать результат в одной (fan-in). Например, извлекли данные — параллельно проверяем их и считаем статистику, затем грузим.
Параллелизм — не просто красивость, а способ сократить время работы конвейера. Если три независимые проверки занимают по 10 минут каждая, последовательно это 30 минут, а параллельно — всего 10. Airflow сам отслеживает, какие задачи готовы к запуску (все предки завершены), и отдаёт их свободным воркерам. Ваша работа — лишь правильно описать зависимости стрелками, а распараллеливание движок берёт на себя.
Как работает под капотом
DAG с ветвлением. Код требует airflow, помечен text.
from airflow import DAG
from airflow.operators.empty import EmptyOperator
from datetime import datetime
with DAG("branch", start_date=datetime(2026,1,1), schedule="@daily", catchup=False) as dag:
extract = EmptyOperator(task_id="extract")
validate = EmptyOperator(task_id="validate")
stats = EmptyOperator(task_id="stats")
load = EmptyOperator(task_id="load")
extract >> [validate, stats] >> loadПроверим логику «задача готова к запуску, когда все её предки завершены» на чистом Python.
done = {"extract", "validate", "stats"}
deps = {"load": ["validate", "stats"], "notify": ["load"]}
for task, need in deps.items():
ready = all(n in done for n in need)
print(task, "готов к запуску" if ready else "ждёт предков")Вывод:
load готов к запуску notify ждёт предков
Эта проверка «все ли предки завершены» — сердце планировщика Airflow. Каждый тик он проходит по графу, находит задачи, у которых все зависимости успешны, и ставит их в очередь на выполнение. Вам не нужно писать эту логику вручную — достаточно описать зависимости стрелками, а движок сам разберётся с порядком и параллелизмом. Именно поэтому DAG-файл получается декларативным: вы описываете что от чего зависит, а не как именно их запускать по шагам.
Частые ошибки
- Перепутать направление стрелки.
a >> b— это «a до b», а не наоборот; ошибка переворачивает весь порядок. - Забыть про fan-in. Если
loadзависит только от одной из параллельных веток, он запустится раньше готовности второй. - Связать задачи из разных DAG напрямую через сдвиг. Оператор сдвига работает внутри одного DAG; между DAG-ами нужны сенсоры или dataset-зависимости.
Итог
- Оператор сдвига задаёт порядок:
a >> b— сначала a, потом b. - Список справа даёт fan-out (параллель), список слева — fan-in (сбор).
- Стрелки — это рёбра графа DAG внутри одного конвейера.