Guides
Apache Airflow

Airflow LocalExecutor: когда Celery это overkill

Настройка Airflow с LocalExecutor вместо CeleryExecutor для небольших инсталляций. Когда хватает LocalExecutor, как наст

Всем привет. Если ваш Airflow-кластер разросся до десятка воркеров на Kubernetes, а мониторинг потребляет больше ресурсов, чем сами DAG, этот материал не для вас. Но если вы только начинаете или ваша инсталляция обрабатывает пару сотен задач в день, вы, скорее всего, стреляете из пушки по воробьям с CeleryExecutor. Давайте разберем, когда и как использовать его простую и эффективную альтернативу — LocalExecutor.

Зачем отказываться от Celery?

CeleryExecutor — это распределенная система с очередями сообщений (RabbitMQ/Redis), отдельными процессами-воркерами и сложностью оркестрации. Он нужен для горизонтального масштабирования. LocalExecutor — это тот же параллельный запуск задач, но в рамках одной машины, используя механизмы многопроцессорности (multiprocessing). Он идеален, когда:

  • У вас один сервер (виртуальная машина, инстанс в облаке).
  • Вы не планируете масштабироваться на десятки нод в ближайшее время.
  • Вы хотите максимальной простоты развертывания и отладки.
  • Ваши задачи в основном “легкие” (Python-операторы, запросы к API, ETL с Pandas) и упираются в I/O, а не в CPU.

Главный плюс — исчезает целый класс проблем: нет битых воркеров Celery, не нужно следить за брокером сообщений, логи всех задач пишутся на одном диске.

Практическая настройка: от Sequential к Local

По умолчанию Airflow стоит с SequentialExecutor, который не дает параллелизма. Переход на Local — дело двух минут.

  1. Создайте базу данных. LocalExecutor требует метаданные в поддерживаемой БД (PostgreSQL или MySQL). SQLite не подойдет, так как он не позволяет конкурентных записей. Пример для PostgreSQL:

    sudo -u postgres psql -c "CREATE DATABASE airflow_db;"
    sudo -u postgres psql -c "CREATE USER airflow_user WITH PASSWORD 'airflow_pass';"
    sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE airflow_db TO airflow_user;"
    
  2. Обновите airflow.cfg. Ключевые параметры:

    [core]
    # Меняем исполнитель
    executor = LocalExecutor
    
    # Указываем строку подключения к Postgres/MySQL
    sql_alchemy_conn = postgresql+psycopg2://airflow_user:airflow_pass@localhost/airflow_db
    
    # Параллелизм на уровне DAG: общее максимальное количество одновременно запущенных задач во всем Airflow.
    parallelism = 32
    
    # Максимальное количество активных задач в одном DAG Run. Защита от "затопления" одним DAG.
    max_active_tasks_per_dag = 16
    
    [scheduler]
    # Сколько задач может быть взято в работу планировщиком за один проход.
    max_dagruns_to_create_per_loop = 10
    
  3. Инициализируйте базу и запустите. После смены конфига:

    airflow db migrate
    airflow users create --username admin --firstname Admin --lastname User --role Admin --email admin@example.com
    # В разных терминалах
    airflow scheduler
    airflow webserver
    

Ключевые отличия от SequentialExecutor

Sequential — это линейная очередь: одна задача за другой. Если задача task1 спит 10 минут, task2 будет ждать. LocalExecutor запускает задачи в отдельных процессах, используя пул. В контексте task1 уснула, но task2, task3 и другие, если для них есть свободные слоты (parallelism), стартуют независимо. Это фундаментальное различие, которое превращает Airflow из планировщика скриптов в оркестратор рабочих нагрузок.

Подводные камни и настройка производительности

  1. Память — ваш главный ограничитель. Каждый процесс-задача потребляет память. Если запустить 32 тяжелых Pandas-операции с parallelism=32, вы можете исчерпать оперативку. Формула для старта: parallelism = (Общая память сервера / Средняя память на задачу) * 0.7. Оставьте запас для системы, шедулера и веб-сервера.

  2. Параметр max_active_tasks_per_dag — ваша защита от “неудачных” DAG. Если в одном DAG 50 задач, все они могут быть запущены одновременно, исчертив parallelism и заблокировав остальные DAG. Выставьте лимит, например, в 8-16.

  3. Монтирование томов и доступ к файлам. Все задачи работают на одной машине, поэтому общие ресурсы (директории, сокеты, Docker-сокет) доступны им напрямую. Это проще, чем в Celery, но следите за конкурентным доступом к файлам.

  4. Шедулер остается единой точкой отказа. Как и в случае с Celery, если падает шедулер — новые задачи не запускаются. Но уже запущенные процессы продолжат работу, так как ими управляет LocalExecutor, а не шедулер.

Итог: LocalExecutor — это мощный и недооцененный инструмент для 80% небольших инсталляций Airflow. Он дает настоящий параллелизм без сложностей распределенных систем. Настройте parallelism в соответствии с ресурсами машины, и вы получите отличный оркестратор для ежедневных ETL-задач.