Airflow на собеседовании Data Engineer
Зачем DE спрашивают про Airflow
Airflow — стандартный инструмент оркестрации batch ETL-пайплайнов. Используется в Yandex, Tinkoff, Ozon, Avito, и почти всех крупных компаниях. На собесе Data Engineer Airflow — обязательный блок: либо отдельным разделом, либо в системном дизайне.
Уровень вопросов: junior — знает синтаксис DAG, операторы; middle — пишет idempotent DAG-и, обрабатывает retry; senior — проектирует архитектуру оркестрации для всей компании, понимает scheduler internals.
Базовая архитектура
Webserver — UI и REST API.
Scheduler — оркестратор: парсит DAG-и, шедулит таски, разделяет работу между workers.
Worker — выполняет таски. Executor: Sequential / Local / Celery / Kubernetes.
Metadata DB — PostgreSQL (default) или MySQL. Хранит DAG runs, task instances, XCom, variables.
DAG bag — каталог DAG-файлов. Scheduler парсит регулярно.
DAG и операторы
DAG — Directed Acyclic Graph. Описание pipeline:
from airflow import DAG
from datetime import datetime
with DAG(
'my_dag',
start_date=datetime(2026, 5, 1),
schedule_interval='@daily',
catchup=False,
max_active_runs=1,
) as dag:
task1 >> task2 >> task3Операторы — типы тасков:
- PythonOperator — выполняет Python-функцию
- BashOperator — bash-команда
- PostgresOperator / MySqlOperator — SQL запросы
- S3ToRedshiftOperator — типовые перемещения
- TaskFlow API (
@taskdecorator) — более pythonic-стиль
Идемпотентность
Главное правило DE — DAG должен быть идемпотентным. Повторный запуск даёт тот же результат.
Почему важно: задачи падают, retries и backfill — обычное дело. Не идемпотентный DAG = дубликаты или потери при retry.
Как достичь:
- Параметризовать по
execution_date. Не использоватьdatetime.now()в DAG. - MERGE / UPSERT вместо INSERT. UPSERT по primary key.
- Delete partition перед записью.
DELETE WHERE date = {{ ds }}; INSERT INTO ... WHERE date = {{ ds }} - Transaction guarantees. Атомарная запись или roll-back.
Sensors
Sensors ждут события: появление файла, новой партиции, статуса внешней системы.
from airflow.sensors.s3_key_sensor import S3KeySensor
wait_for_file = S3KeySensor(
task_id='wait_for_data',
bucket_key='s3://bucket/data/{{ ds }}/*.parquet',
poke_interval=60,
timeout=3600,
)Проблема: sensors занимают worker-slot всё время ожидания. Решение — reschedule mode (mode='reschedule'). Sensor отпускает слот между проверками.
Smart sensor / Deferrable operators — Airflow 2+ — sensors работают через async без блокировки слотов.
XCom
XCom — передача данных между тасками. Хранится в metadata DB.
def push_data(**context):
context['ti'].xcom_push(key='result', value=42)
def pull_data(**context):
value = context['ti'].xcom_pull(task_ids='push_task', key='result')Ограничения:
- Размер: только маленькие payload-ы (метаданные, IDs). XCom хранится в metadata DB
- Performance: каждый XCom — запись в metadata DB
Для больших данных: передавай через external storage (S3 path), а через XCom — только путь.
Backfill
Backfill — запуск DAG-а на исторический период. Например, новый pipeline для последних 90 дней:
airflow dags backfill my_dag --start-date 2026-02-01 --end-date 2026-05-01Требования к backfill:
- DAG должен быть идемпотентным
catchup=Falseилиcatchup=True— выбор архитектораdepends_on_past=Trueесли порядок важен
Scheduler internals
DAG parsing — scheduler регулярно парсит DAG-файлы. Если 1000 DAG-ов с медленными импортами — scheduler тормозит.
Trigger rules:
all_success(default) — все upstream успешноone_success— хотя бы одинall_failed— все провалилисьone_failed— хотя бы одинall_done— все завершены (любой статус)
Pool — ограничение параллелизма по группе задач. Например, «к одной БД не более 5 задач».
Типичные вопросы
«Что значит идемпотентность DAG?»
Многократный запуск даёт тот же результат. Достигается через параметризацию по execution_date, MERGE вместо INSERT, удаление целевой партиции перед записью.
«Чем catchup=True отличается от catchup=False?»
catchup=True — Airflow запустит DAG за все прошедшие интервалы с start_date. catchup=False — только начиная с текущего момента. По умолчанию True, в production обычно False (если не нужен исторический запуск).
«DAG не запускается. Что проверить?»
(1) Включён ли (paused/unpaused), (2) start_date — в прошлом ли, (3) schedule_interval не пустой, (4) max_active_runs не ограничивает, (5) scheduler здоров (логи), (6) dependencies upstream success.
«Как обработать late-arriving данные?»
Несколько вариантов: (1) повторный запуск нужных партиций (backfill), (2) DAG ждёт данные через sensor с timeout, (3) отдельный «reprocessing» DAG для late events.
«XCom для больших данных?»
Не используй XCom для больших объёмов. Передавай через external storage — S3, HDFS, ClickHouse table. Через XCom — только path или ID.
Частые ошибки
datetime.now()в DAG. Делает DAG неидемпотентным. Используй{{ ds }}илиexecution_date- Insert вместо MERGE. При retry получаешь дубликаты
- Большие XCom. Забивает metadata DB
- Sensor без
reschedule mode. Занимает worker-slot часами - Тяжёлые импорты в DAG-файле. Тормозит scheduler
FAQ
Какие альтернативы Airflow?
Dagster — современная альтернатива, фокус на data assets. Prefect — лёгкий, Python-native. Luigi — старый, ещё используется. На собесе обычно Airflow — стандарт de facto.
Airflow 2 vs 3?
Airflow 2 — мейнстрим в 2024-2026. Airflow 3 в активной разработке. На собесе обычно про 2.x.
Какие книги?
«Data Pipelines with Apache Airflow» (Harenslak) — главная книга. Также официальная документация.
Сколько готовиться к Airflow-блоку?
С нуля — 1-2 месяца с практикой. Уже работал — 2-4 недели.
Спрашивают ли scheduler internals?
На senior — да. На middle — общее понимание (DAG parsing, scheduler/worker разделение).