Executor란 무엇인가
Airflow Scheduler는 어떤 Task를 언제 실행할지 결정하지만, 그 Task를 어디서, 어떤 방식으로 실행할지는 Executor가 담당한다. Executor는 Airflow의 실행 계층이며, 개발 환경부터 대규모 프로덕션까지 상황에 맞는 선택이 중요하다.
# airflow.cfg
[core]
executor = LocalExecutor주요 Executor 한눈에 보기
| Executor | 실행 위치 | 병렬성 | 추가 인프라 | 주 용도 |
|---|---|---|---|---|
SequentialExecutor | Scheduler 프로세스 내 | 순차 (1개) | 없음 | 테스트·디버깅 |
LocalExecutor | Scheduler 서버 내 서브프로세스 | O (CPU 코어 수까지) | 없음 | 소규모 프로덕션 |
CeleryExecutor | 별도 Worker 서버 | O (수평 확장) | Celery + 브로커(Redis/RabbitMQ) | 중대규모 프로덕션 |
KubernetesExecutor | K8s Pod (Task마다 1개) | O (Pod 단위) | Kubernetes 클러스터 | 자원 격리·동적 스케일링 |
SequentialExecutor
설치 직후 SQLite와 함께 사용되는 기본 Executor다. Task를 하나씩 순서대로 실행하며, 병렬 실행이 불가능하다.
- 장점: 의존성 없음, 즉시 시작 가능.
- 단점: 실제 워크로드에는 사용 불가. SQLite 한계와 결합되어 있다.
- Airflow 3.0 이후: SequentialExecutor가 제거되고 LocalExecutor가 그 역할을 대신한다. SQLite 대신 PostgreSQL/MySQL을 사용해야 한다.
LocalExecutor
Scheduler와 같은 머신에서 서브프로세스를 fork해 Task를 병렬 실행한다.
[core]
executor = LocalExecutor
parallelism = 32 # 동시 실행 Task 수 상한- 장점: 별도 인프라 불필요, 설정이 단순하다. 소규모 팀·단일 서버 환경에 적합.
- 단점: Scheduler 서버 한 대에 종속. 서버 재시작 시 실행 중인 Task가 중단된다. 메모리 압박 주의(fork 방식은 모든 워커가 Scheduler 메모리를 복사).
- PostgreSQL 또는 MySQL 필수 (SQLite 미지원).
CeleryExecutor
(Redis / RabbitMQ) ↓ Task 메시지 큐
Task를 메시지 브로커(Redis 또는 RabbitMQ)를 통해 별도 Worker 서버에 분배한다. Worker를 수평으로 확장할 수 있어 높은 처리량을 달성할 수 있다.
[core]
executor = CeleryExecutor
[celery]
broker_url = redis://redis:6379/0
result_backend = db+postgresql://user:pass@postgres/airflow- 장점: Worker 서버를 자유롭게 추가해 수평 확장. Scheduler 장애 시에도 Worker는 기존 Task를 계속 처리.
- 단점: 브로커 인프라(Redis/RabbitMQ)와
celeryWorker 프로세스 관리가 추가된다. 운영 복잡도 증가. - Flower: Celery Worker 상태를 모니터링하는 UI. 보통 함께 배포한다.
업계에서는 중규모 이상의 프로덕션 Airflow 환경의 60% 이상이 CeleryExecutor를 사용한다고 알려져 있다.
KubernetesExecutor
Task가 시작될 때마다 Kubernetes Pod를 하나 생성하고, Task 완료 후 Pod를 종료한다. Task별로 컨테이너 이미지·CPU·메모리·환경변수를 독립적으로 지정할 수 있다.
# Task별 리소스 지정 예시
from kubernetes.client import models as k8s
@task(
executor_config={
"pod_override": k8s.V1Pod(
spec=k8s.V1PodSpec(
containers=[
k8s.V1Container(
name="base",
resources=k8s.V1ResourceRequirements(
requests={"cpu": "2", "memory": "4Gi"},
limits={"cpu": "4", "memory": "8Gi"},
),
)
]
)
)
}
)
def heavy_ml_task():
...- 장점: Task별 완벽한 환경 격리. 유휴 시 Worker 리소스 낭비 없음(Pod는 Task 실행 중에만 존재). K8s 스케줄러가 자원 배분을 담당.
- 단점: Pod 시작 오버헤드(수 초~수십 초). Kubernetes 인프라 필수. 빠른 단기 Task가 많은 환경에서는 Pod 기동 비용이 문제가 될 수 있다.
Airflow 3.0: 복수 Executor 동시 사용
Airflow 3.0에서 CeleryKubernetesExecutor 같은 정적 하이브리드 Executor가 제거됐다. 대신 단일 DAG 안에서 Task별로 다른 Executor를 지정하는 방식이 도입됐다.
# airflow.cfg — 두 Executor 동시 등록
[core]
executor = CeleryExecutor,KubernetesExecutor@task(executor="KubernetesExecutor") # 이 Task만 K8s Pod에서 실행
def heavy_task():
...
@task(executor="CeleryExecutor") # 이 Task는 Celery Worker에서
def light_task():
...이 방식은 혼합 워크로드(일부 Task는 빠른 Celery, 일부는 격리된 K8s Pod 필요)를 유연하게 처리할 수 있다.
Executor 선택 가이드
소규모 팀? ↓ LocalExecutor
수평 확장 필요? ↓ CeleryExecutor
Task 격리 필요? ↓ KubernetesExecutor
| 상황 | 권장 Executor |
|---|---|
| 로컬 개발·테스트 | LocalExecutor |
| 소규모 단일 서버 프로덕션 | LocalExecutor |
| 중대규모, Worker 수평 확장 필요 | CeleryExecutor |
| Kubernetes 환경, Task별 격리 | KubernetesExecutor |
| 혼합 워크로드 (Airflow 3.0+) | 복수 Executor 동시 사용 |
References
- https://airflow.apache.org/docs/apache-airflow/stable/core-concepts/executor/index.html
- https://airflow.apache.org/docs/apache-airflow/stable/core-concepts/executor/local.html
- https://www.astronomer.io/docs/learn/airflow-executors-explained
- https://moldstud.com/articles/p-understanding-apache-airflow-executor-types-answering-common-user-questions
- https://medium.com/brilliant-programmer/difference-between-sequential-executor-vs-local-executor-vs-celery-executor-vs-kubernates-executor-f56016dfc8e
- https://www.mail-archive.com/[email protected]/msg415446.html