# 탄생 배경
과거의 데이터 파이프라인은 주로 리눅스의 크론(Cron)과 쉘 스크립트에 의존하여 구축되었다.
그러나 처리해야 할 데이터의 소스와 파이프라인의 규모가 기하급수적으로 커짐에 따라 심각한 한계에 직면했다.
작업 간의 선후 관계, 즉 의존성을 설정하고 관리하기가 매우 까다로웠으며 특정 작업이 실패했을 때
하위 작업을 일시 중단하거나 실패 지점부터 재시도하는 로직을 일일이 구현해야 하는 이른바 크론 지옥(Crontab Hell)이 발생했다.
또한, 전체 파이프라인의 분산된 실행 상태를 한눈에 파악할 수 있는 중앙 관제 모니터링 시스템의 부재로 인해 장애 추적 및 복구에 막대한 엔지니어링 리소스가 소모되었다.
에어플로우는 이러한 레거시 환경의 의존성 관리 부재, 실패 처리의 복잡성, 그리고 모니터링의 사각지대 문제를 근본적으로 해결하기 위해 개발되었으며
데이터 워크플로우를 코드로 정의(Configuration as Code)하는 현대적인 오케스트레이션 표준으로 자리 잡았다.

# Airflow란?
Airflow는 Python 코드로 워크플로우(workflow)를 작성하고, 스케쥴링, 모니터링 하는 플랫폼이다.
Airflow를 통해서 데이터엔지니어링의 ETL 작업을 자동화하고, DAG(Directed Acyclic Graph) 형태의 워크플로우 작성이 가능하다.
이를 통해 더 정교한 dependency를 가진 파이프라인을 설정할 수 있다.
동작의 큰 흐름은 이렇다.
개발자가 Python으로 DAG 파일을 작성하면, Airflow의 스케줄러가 그 파일을 주기적으로 읽어 어떤 작업을 언제 실행할지 판단한다.
실행해야 할 작업이 생기면 워커(Worker)에게 넘기고, 워커가 실제 작업을 수행한다.
모든 과정은 메타데이터 데이터베이스에 기록되며, 웹 UI를 통해 사람이 실시간으로 파이프라인의 상태를 감시하고 제어할 수 있다.

DAG는 전체 파이프라인의 설계도, Task는 그 안의 개별 단계, Operator는 그 단계가 무엇을 실행할지 정의하는 타입입니다.
- DAG (Directed Acyclic Graph) : Python 코드로 정의하며, 방향이 있고 순환이 없는 그래프 구조로 워크플로우를 표현한다.
중요한 점은, DAG 파일 자체는 실행 로직을 기술하는 것이지 실행하는 것이 아니라는 것. 실제 실행은 Worker 프로세스가 담당한다.
- Task : DAG 안에서 실행되는 개별 작업의 단위.
- Operator : Task가 구체적으로 무엇을 할지 정의하는 템플릿. Python을 실행할지, SQL을 실행할지, HTTP 요청을 보낼지 등을 결정한다.
핵심 컴포넌트

- Scheduler — DAG 파일을 읽고, 실행 조건이 충족된 Task를 찾아 실행 대기열에 올리는 핵심 컴포넌트.
- Executor — Task를 실제로 어떤 방식으로 실행할지 결정하는 엔진. (로컬에서 실행할지, Celery 워커 클러스터에서 실행할지, Kubernetes Pod에서 실행할지를 담당한다.)
- Web Server — 브라우저에서 볼 수 있는 UI를 제공한다. 실행 상태 확인, 수동 트리거 등을 여기서 한다.
- Worker — 실제 Task 코드를 실행하는 프로세스.
- Metadata Database — 모든 DAG 실행 이력, Task 상태, 변수 등을 저장하는 관계형 데이터베이스
- XCom (Cross-Communication) — Task 간에 소량의 데이터를 주고받기 위한 메시지 전달 메커니즘.
- Connection & Hook — 외부 시스템(데이터베이스, 클라우드, API 등)에 연결하기 위한 자격증명 관리 및 인터페이스 계층.
- Sensor — 특정 조건이 충족될 때까지 대기하는 특수한 형태의 Operator. 파일이 생길 때까지, 혹은 API가 응답할 때까지 기다리는 역할을 한다.
- Backfill — 과거 특정 기간에 대해 DAG를 소급하여 실행하는 기능.
- Pool — Task 동시 실행 수를 제한하기 위한 자원 관리 단위.
실행 흐름
Scheduler가 DAG 폴더를 주기적으로 스캔하면서 "지금 실행해야 할 DAG가 있나?" 확인한다.
실행 시각이 되면 DagRun(특정 시각의 DAG 실행 인스턴스)을 만들고, 안의 Task들을 DB에 queued 상태로 기록한다.
Worker가 이를 보고 가져가 실행하며, 끝나면 DB에 success 또는 failed를 쓴다.
Web Server는 이 DB를 읽어 화면에 보여주는 역할만 한다.

# 설계시 주요 포인트
멱등성 유지하기
멱등성이란 "같은 Task를 몇 번 실행해도 결과가 동일하다"는 성질이다.
Airflow에서 이게 왜 중요하냐면, Task는 언제든 재실행될 수 있기 때문이다.
핵심 원칙은 "이 Task가 처리하는 데이터 범위(보통 날짜)를 명확히 하고, 그 범위를 실행 전에 지운 뒤 다시 쓴다" 이다.
Airflow는 context["ds"](실행 날짜), context["data_interval_start/end"] , execution_date 같은 변수를 제공하므로, 이 값을 적극 활용하는 게 정석이다.
실무에서는 멱등성을 위한 특정 날짜 파라미터로 따로 관리 했다.
- context["ds"](실행 날짜) : 논리적 날짜(Logical Date, 과거의 execution_date)를 YYYY-MM-DD 형식의 문자열로 가져오는 내장 변수
Catchup과 Backfill
catchup은 DAG 설정값이다.
start_date부터 현재까지 실행되지 않은 구간이 있으면 자동으로 소급 실행할지 여부이다.
프로덕션에서는 catchup=False가 안전 하다. (의도치 않은 대량 실행 방지)
dag = DAG(
"my_dag",
start_date=datetime(2026, 1, 1),
schedule_interval="@daily",
catchup=True # 기본값 — 오늘이 1월 10일이면 1/1~1/9 자동 실행
# catchup=False — 오늘부터만 실행
)
backfill은 명령어이다.
이미 실행된 구간을 의도적으로 다시 실행하거나, 특정 기간만 골라 실행할 때 쓴다.
# 1월 1일부터 1월 10일까지 my_dag를 다시 실행
airflow dags backfill -s 2026-01-01 -e 2026-01-10 my_dag
⇒ "catchup은 자동 소급, backfill은 수동 재처리이고, 둘 다 멱등성이 보장되어야 의미 있다"
Executor 선택
Executor는 Task를 실행시키는 주체로 스케줄러 프로세스 내부에서 동작한다.
Airflow에서는 여러 executor를 제공하는데 각 executor 마다 작업 전달 방식 및 워커의 작동 방식도 조금씩 달라진다.

- SequentialExecutor:
기본 셋팅 설정. 병렬 실행 불가능하다. Scheduler 프로세스 안에서 Task를 한 번에 하나씩 직접 실행한다. 별도 Worker도 없고 Message Queue도 없다.
SQLite만 지원하기 때문에 로컬에서 DAG가 문법적으로 맞는지 확인할 때만 쓰고, 실제 운영에서는 절대 쓰지 않는다.
- LocalExecutor: 같은 서버 안에서 fork()로 자식 프로세스를 만들어 Task를 실행한다.. Message Queue 없이 동시에 여러 Task를 처리할 수 있다.
- CeleryExecutor: 가장 널리 쓰이는 프로덕션 선택이다 . Message Queue를 중간에 두고 Worker 서버를 분리한다.
- KubernetesExecutor: Task 하나가 실행될 때마다 Kubernetes Pod를 새로 만들고, 끝나면 삭제한다. Worker 서버라는 개념 자체가 없다.
'3. Data Engineering > ㅤ📘 데이터 웨어하우스' 카테고리의 다른 글
| iceberg , 아이스버그 개념 및 아키텍처 (0) | 2026.02.28 |
|---|---|
| [Parquet 공식문서] 파케이 개념 및 아키텍처 (0) | 2026.02.28 |
| Oozie, 우지의 기본 개념 (0) | 2026.02.25 |
| impala, 임팔라 엔진의 데이터 검색 (1) | 2026.02.23 |
| Impala, 임팔라의 기본 개념 및 메커니즘 (0) | 2026.02.22 |