В чем разница между Cron и Airflow?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
# Cron vs Airflow: сравнение систем планирования задач
Это хороший вопрос, потому что выбор между ними зависит от сложности задач. Расскажу о различиях и когда какой использовать.
Что такое Cron
Cron — это встроенный в Unix/Linux планировщик задач, который запускает команды по расписанию.
Простой пример Cron
# Добавить в crontab
crontab -e
# Запускать Python скрипт каждый день в 3:00 утра
0 3 * * * /usr/bin/python3 /home/user/backup.py
# Запускать каждые 15 минут
*/15 * * * * /home/user/update_cache.sh
# Запускать в понедельник в 9:00
0 9 * * 1 /home/user/weekly_report.py
Формат crontab:
┌───────────── minute (0 - 59)
│ ┌───────────── hour (0 - 23)
│ │ ┌───────────── day of month (1 - 31)
│ │ │ ┌───────────── month (1 - 12)
│ │ │ │ ┌───────────── day of week (0 - 6) (Sunday to Saturday)
│ │ │ │ │
│ │ │ │ │
0 3 * * * /path/to/script.py
Что такое Airflow
Apache Airflow — это платформа для программного определения, планирования и мониторинга рабочих процессов (DAGs — Directed Acyclic Graphs).
Простой пример Airflow
from datetime import datetime, timedelta
from airflow import DAG
from airflow.operators.python import PythonOperator
def extract_data():
print("Extracting data...")
def transform_data():
print("Transforming data...")
def load_data():
print("Loading data...")
# Определяем DAG (направленный ациклический граф)
default_args = {
'owner': 'airflow',
'retries': 1,
'retry_delay': timedelta(minutes=5),
'start_date': datetime(2024, 1, 1),
}
dag = DAG(
'etl_pipeline',
default_args=default_args,
description='ETL pipeline',
schedule_interval='0 3 * * *', # Каждый день в 3:00
)
# Задачи
extract_task = PythonOperator(
task_id='extract',
python_callable=extract_data,
dag=dag,
)
transform_task = PythonOperator(
task_id='transform',
python_callable=transform_data,
dag=dag,
)
load_task = PythonOperator(
task_id='load',
python_callable=load_data,
dag=dag,
)
# Зависимости (порядок выполнения)
extract_task >> transform_task >> load_task
Визуальное сравнение
╔════════════════════════════════════════════════════════╗
║ CRON ║
╠════════════════════════════════════════════════════════╣
║ 0 3 * * * /usr/bin/python3 /home/backup.py ║
║ ║
║ 3:00 AM → run backup.py ║
║ ║
║ [Script works or fails] ← No visibility ║
║ ║
║ Done (success/error lost in logs) ║
╚════════════════════════════════════════════════════════╝
╔════════════════════════════════════════════════════════╗
║ AIRFLOW ║
╠════════════════════════════════════════════════════════╣
║ DAG: etl_pipeline ║
║ ║
║ 3:00 AM ↓ ║
║ [extract_data] ← Task 1 ║
║ ↓ (success) ║
║ [transform_data] ← Task 2 ║
║ ↓ (success) ║
║ [load_data] ← Task 3 ║
║ ↓ ║
║ [Status: Success] ← Webui tracking ║
║ ║
║ Full logs, metrics, alerts ║
╚════════════════════════════════════════════════════════╝
Таблица детального сравнения
| Аспект | Cron | Airflow |
|---|---|---|
| Сложность | Простой — одна команда | Сложный — DAGs с зависимостями |
| Установка | Встроен в Unix/Linux | Требует установки (pip install apache-airflow) |
| Конфигурация | Text файл (crontab) | Python код (DAG файлы) |
| Зависимости | Нет — каждая задача независима | Да — задачи могут зависеть друг от друга |
| Мониторинг | Только логи и email | WebUI, метрики, alerts, сложный tracking |
| Масштабируемость | До 100s задач | 1000s задач, распределённый |
| Retry логика | Нужна своя в скрипте | Встроена (retries, backoff) |
| Обработка ошибок | Manual — нужно ловить exit codes | Автоматическая — failed tasks, branching |
| Условное выполнение | Нужна собственная логика | Встроено — branching, XCom |
| Управление зависимостями | Manual управление | Явное определение (task >> task) |
| Data passing | Через файлы или БД | XCom (встроенный механизм) |
| История запусков | Только в логах | Полная история в БД |
| Параллелизм | Последовательный | Параллельный с управлением |
| Версионирование | Простая history | Git + Airflow version control |
Практические примеры
Cron: когда подходит
Ситуация 1: Простой скрипт резервной копии
# Каждый день в 2:00 AM
0 2 * * * /usr/bin/python3 /scripts/backup_db.py >> /var/log/backup.log 2>&1
# Скрипт просто работает или падает
# Оповещение — через системный mail
Ситуация 2: Очистка старых файлов
# Каждый месяц в первый день
0 0 1 * * find /tmp -type f -mtime +30 -delete
Airflow: когда подходит
Ситуация 1: ETL пайплайн с зависимостями
# Нужно:
# 1. Загрузить данные из API
# 2. Трансформировать (зависит от 1)
# 3. Загрузить в БД (зависит от 2)
# 4. Создать отчёт (зависит от 3)
# + retry каждого шага отдельно
# + видеть прогресс в UI
В cron это невозможно элегантно сделать.
Ситуация 2: Сложный ML pipeline
DAG: model_training
├─ [fetch_data]
│ └─ [preprocess_data]
│ ├─ [train_model_v1]
│ └─ [train_model_v2] (параллельно)
│ └─ [evaluate_models]
│ ├─ [if v1 better] → deploy_v1
│ └─ [if v2 better] → deploy_v2
│ └─ [monitor_model]
└─ [notify_team]
Такой граф в cron — кошмар!
Ситуация 3: Data pipeline с error handling
with DAG('data_pipeline') as dag:
# Если load_data падает, retry 3 раза
load = PythonOperator(
task_id='load_data',
python_callable=load_from_api,
retries=3,
retry_delay=timedelta(minutes=5),
)
# Если load успешен, трансформировать
transform = PythonOperator(
task_id='transform',
python_callable=transform_data,
)
# После трансформа отправить email с отчётом
notify = EmailOperator(
task_id='send_report',
to=['team@company.com'],
)
load >> transform >> notify
Когда какой использовать
Используй Cron если:
- ✅ Одна простая задача (backup, clean cache)
- ✅ Нет зависимостей между задачами
- ✅ Нет сложной логики обработки ошибок
- ✅ Нужна минимальная инфраструктура
- ✅ Задача работает в одной системе
- ✅ Не нужен WebUI для мониторинга
# Простая задача — cron отлично подходит
0 * * * * python3 /scripts/update_cache.py
Используй Airflow если:
- ✅ Несколько взаимозависимых задач
- ✅ Сложная логика ветвления (if/else)
- ✅ Нужна автоматическая retry логика
- ✅ Нужно передавать данные между задачами
- ✅ Нужен мониторинг через WebUI
- ✅ Нужна история всех запусков
- ✅ Нужно параллельное выполнение
- ✅ Много задач (100+)
# Сложный пайплайн — Airflow необходим
load >> [transform, validate] >> merge >> load_db >> notify
Гибридный подход
На практике часто используют оба инструмента:
# Cron запускает Airflow DAG в определённое время
0 3 * * * curl -X POST http://localhost:8080/api/v1/dags/etl_pipeline/dagRuns
# Или используют Airflow с Cron-like schedule:
@dag(
schedule_interval='0 3 * * *', # Как в cron
)
Пример: миграция от Cron к Airflow
Было (Cron):
0 2 * * * python3 /scripts/data_sync.py
0 3 * * * python3 /scripts/generate_report.py
0 4 * * * python3 /scripts/cleanup.py
Проблемы:
- Нет зависимостей
- Если первый скрипт падает, второй запускается в пустую
- Нет видимости
- Нет автоматического retry
Стало (Airflow):
from airflow import DAG
from airflow.operators.python import PythonOperator
from datetime import datetime
dag = DAG(
'data_sync_pipeline',
schedule_interval='0 2 * * *',
start_date=datetime(2024, 1, 1),
)
sync_task = PythonOperator(
task_id='sync_data',
python_callable=sync_data,
retries=3,
dag=dag,
)
report_task = PythonOperator(
task_id='generate_report',
python_callable=generate_report,
retries=2,
dag=dag,
)
cleanup_task = PythonOperator(
task_id='cleanup',
python_callable=cleanup,
dag=dag,
)
sync_task >> report_task >> cleanup_task
Преимущества:
- Ясные зависимости
- Если sync_task падает, остальные не запускаются
- WebUI показывает статус
- Автоматический retry каждого шага
- История всех запусков
Резюме
| Критерий | Выбор |
|---|---|
| Одна простая задача | Cron |
| Несколько независимых задач | Cron (или несколько cron entries) |
| Задачи с зависимостями | Airflow |
| Нужно передавать данные между задачами | Airflow |
| Нужна сложная retry логика | Airflow |
| Нужен мониторинг и история | Airflow |
| Много задач (100+) | Airflow |
| Стартап, простой проект | Cron |
| Enterprise, сложные пайплайны | Airflow |
Практическая рекомендация:
- Начни с Cron для простых задач
- Когда сложность растёт и появляются зависимости — переходи на Airflow
- Cron хорош для системного администрирования, Airflow — для data engineering и ML