Blog
airfloworchestrationdata-pipelineairflow3etl

Airflow 3 실전 연재 0편: 왜, 그리고 언제 쓰나

워크플로 오케스트레이션이 푸는 문제부터 Airflow 3의 핵심 변화, 그리고 12편짜리 실전 연재 로드맵까지.

Data Dynamics2026年6月24日15 min read
This post is not yet translated. The original Korean version is shown below.

이 글은 "Airflow 3 실전 연재"의 0편입니다. 본격적인 아키텍처 해부나 클러스터 구성에 들어가기 전에, 한 발 물러서서 "그래서 왜 Airflow인가, 그리고 언제 쓰는 게 맞는가"를 먼저 정리합니다. 처음 워크플로 오케스트레이션을 접하는 분도 끝까지 따라올 수 있도록 천천히 풀어 쓰겠습니다. 다음 편부터는 1편: 아키텍처 해부에서 내부 구조를 파헤칩니다.

cron과 스크립트로 버티던 시절의 한계

데이터 파이프라인이 두세 개일 때는 cron 한 줄이면 충분합니다. "매일 새벽 3시에 추출 스크립트 실행, 4시에 적재 스크립트 실행." 문제는 파이프라인이 늘어나고, 단계 사이에 의존성이 생기는 순간 시작됩니다.

cron이나 셸 스크립트 묶음으로 일정 규모를 넘기면 거의 항상 다음 세 가지가 발목을 잡습니다.

  • 의존성 표현이 안 된다. "추출이 끝나야 변환을 돌린다"를 cron은 모릅니다. 그래서 사람들은 "추출은 보통 30분 걸리니까 변환은 그 30분 뒤에 시작"처럼 시간으로 때웁니다. 추출이 35분 걸리는 날, 변환은 미완성 데이터를 읽습니다.
  • 재시도와 실패 처리가 없다. 스크립트가 중간에 죽으면? cron은 그냥 다음 스케줄까지 침묵합니다. 재시도 로직, 백오프, 부분 재실행을 전부 스크립트 안에 손으로 짜 넣어야 합니다.
  • 관측 가능성이 없다. 어제 밤 파이프라인이 어디까지 돌았는지, 어느 단계가 얼마나 걸렸는지, 왜 실패했는지를 보려면 서버에 SSH로 들어가 로그를 뒤져야 합니다. "지난주 화요일 적재가 왜 비었지?"에 답하기가 사실상 불가능합니다.

이 세 가지 결핍을 한 그림으로 비교하면 이렇습니다.

Loading diagram…

cron은 "언제 실행할지"만 압니다. 오케스트레이터는 "무엇이 무엇에 의존하고, 실패하면 어떻게 하고, 지금 어디까지 왔는지"를 압니다.

그래서 오케스트레이터가 푸는 문제

워크플로 오케스트레이터는 작업들을 **방향성 비순환 그래프(DAG, Directed Acyclic Graph)**로 표현합니다. 노드는 할 일(태스크), 엣지는 "이게 끝나야 저게 돈다"는 의존성입니다. 오케스트레이터는 이 그래프를 보고 다음을 자동으로 해줍니다.

  • 의존성 순서대로 태스크 스케줄링 (병렬 가능한 건 병렬로)
  • 실패 시 재시도, 백오프, 알림
  • 실행 이력·로그·소요 시간의 중앙 집중 기록과 시각화
  • 과거 구간 재실행(backfill), 수동 트리거, 일시 중지

Airflow는 이 영역에서 가장 널리 쓰이는 오픈소스이고, DAG를 Python 코드로 정의한다는 점이 특징입니다. YAML이나 GUI가 아니라 코드라서 버전 관리·테스트·코드 리뷰가 그대로 됩니다.

Airflow가 잘 맞는 경우 / 아닌 경우

도구는 만능이 아닙니다. Airflow가 빛나는 자리와 그렇지 않은 자리를 솔직히 구분하면 이렇습니다.

잘 맞는 경우

  • 배치 중심 ETL/ELT, 데이터 웨어하우스 적재, 주기적 리포트 생성
  • 단계가 여럿이고 서로 의존하는 파이프라인 (수십~수천 개 태스크)
  • 이기종 시스템을 엮는 작업 (DB → S3 → Spark → BI)
  • 스케줄 + 백필 + 재실행 이력이 중요한 운영

잘 안 맞는 경우

  • 밀리초 단위 저지연 스트리밍 (그건 Kafka/Flink 영역)
  • 요청-응답형 실시간 API 처리
  • 초당 수천 건의 초경량 이벤트 처리 (스케줄러 오버헤드가 부담)

Airflow는 "스트리밍 엔진"이 아니라 "배치 오케스트레이터"입니다. 실시간 처리를 Airflow로 우겨넣으려는 순간이 보통 잘못된 도구 선택의 신호입니다.

대안과의 간단 비교

오케스트레이터 생태계에는 좋은 대안이 여럿 있습니다. 절대적 우열보다 "성향 차이"로 이해하는 편이 좋습니다.

도구정의 방식강점주로 맞는 자리
AirflowPython DAG가장 넓은 생태계·통합(provider), 성숙한 운영 도구범용 배치 ETL, 복잡한 의존성, 대규모 스케줄
PrefectPython 함수 데코레이터동적 워크플로, 가벼운 개발자 경험파이썬 중심 팀, 동적·이벤트성 흐름
DagsterAsset 중심 (소프트웨어 정의 자산)데이터 자산·타입·테스트 일급 지원데이터 자산 계보·품질을 모델링하려는 팀
Argo WorkflowsKubernetes CRD(YAML)컨테이너 네이티브, K8s 친화K8s 위 컨테이너 단위 파이프라인

흥미롭게도 Airflow 3은 뒤에서 볼 Asset(자산) 기반 스케줄링을 도입하면서, Dagster가 강조하던 "데이터 자산 중심" 사고를 상당히 흡수했습니다.

Airflow 2.x → 3.x, 무엇이 달라졌나

이 연재는 전부 Airflow 3.0/3.x(2025년 GA) 기준입니다. 2.x를 써본 분이라면 바뀐 지점을 먼저 머리에 넣어두면 나머지 편이 훨씬 수월합니다. 핵심만 추리면 다음과 같습니다.

영역2.x3.x의미
웹 컴포넌트WebserverAPI server (UI + REST API 통합)UI와 안정·버전드 REST API를 한 컴포넌트가 제공
DAG 파싱스케줄러 내부DAG processor 분리DAG 파싱을 독립 프로세스로 격리(안정성·보안)
태스크 실행워커가 메타DB 직접 접속Task SDK + Task Execution API워커는 API server를 통해 통신 → 원격/언어 비종속 실행
데이터 인지 스케줄DatasetAsset (@asset, schedule=[asset])용어·기능 정리, 자산 중심 스케줄링
실행 추적버전 개념 약함DAG versioning어떤 버전 DAG로 실행됐는지 UI에서 추적
백필CLI 위주스케줄러 관리 backfill (UI/API)UI/API에서 트리거하면 스케줄러가 수행
catchup 기본값TrueFalse새 DAG가 과거 구간을 무더기로 돌리는 사고 예방
시간 필드execution_datelogical_date (또는 data_interval_*)execution_date 제거, 수동/자산 트리거 시 None 가능
제거된 것SubDAG, SLA, 구 experimental REST APITaskGroup/Asset, Deadline, 안정 REST API로 대체혼란스러운 레거시 정리
ExecutorLocal/Celery/Kubernetes+ EdgeExecutor, 그리고 hybrid(동시 다중)HTTP 기반 원격/엣지 워커, 여러 executor 병행

임포트 경로도 바뀌었습니다. 3.x에서는 airflow.sdk가 권장 진입점입니다.

from airflow.sdk import dag, task, Asset
 
@dag(schedule="@daily", catchup=False)  # 3.x에서 catchup 기본값은 False
def daily_etl():
    @task
    def extract():
        return {"rows": 1000}  # 예시 값
 
    @task
    def load(payload: dict):
        print(f"적재 행 수(예시): {payload['rows']}")
 
    load(extract())
 
daily_etl()

이 코드가 왜 이렇게 생겼고 내부에서 무슨 일이 벌어지는지는 4편: DAG 작성의 정석에서 깊게 다룹니다. 여기서는 "워커가 더 이상 메타DB에 직접 붙지 않고 Task Execution API를 거친다"는 구조적 변화 하나만 기억하면 충분합니다.

이 연재에서 배울 것 (로드맵)

전체 흐름은 "왜 → 구조 → 구성 → 작성 → 연동 → 운영"의 순서로 짰습니다. 한 장으로 보면 이렇습니다.

Loading diagram…

각 편의 링크는 아래 목차에서 바로 이동할 수 있습니다.

제목한 줄 요지
0(지금 이 글) 시리즈 개요 & 언제 쓰나오케스트레이션의 문제 정의와 3.x 변화 개관
1아키텍처 해부Scheduler·API server·DAG processor·Triggerer·Worker가 어떻게 맞물리나
2클러스터로 구성하기단일 노드를 넘어 컴포넌트를 분리 배치하기
3환경설정 & 최적화동시성 3계층·Pool·자원 격리 튜닝
4DAG 작성의 정석Task SDK, 데코레이터, TaskGroup, 베스트 프랙티스
5DAG 고급 테크닉스크립트·파라미터·에러 처리·PostgreSQL·재실행·날짜 기준
6스케줄링 & Assetcron 스케줄과 자산 기반(asset-driven) 스케줄링
7XCom & 데이터 전달태스크 간 데이터 전달과 그 한계
8외부 시스템 연동 & 싱크 호출Connection·Hook·provider, deferrable 패턴
9REST API & 원격 스케줄 변경JWT 인증 REST API로 원격 트리거·제어
10모니터링 & 운영메트릭·알림·로그·SLA 대체(Deadline)
11테스트·CI/CD·보안DAG 테스트, 파이프라인, 권한·시크릿 관리
12프로덕션 체크리스트운영 투입 전 점검할 모든 것

정리하며

오케스트레이션의 본질은 "의존성·재시도·관측"이라는 cron의 세 결핍을 메우는 일입니다. Airflow는 그걸 Python 코드로 표현하는 성숙한 도구이고, 3.x에 와서 API server/DAG processor 분리, Task Execution API, Asset 스케줄링으로 구조가 한층 깔끔해졌습니다. 다만 실시간 스트리밍처럼 결이 다른 일에는 다른 도구를 쓰는 게 맞습니다.

도구 선택의 출발점은 "내 워크로드가 배치 의존성 그래프인가?"라는 질문입니다. 그렇다면 Airflow는 거의 항상 후보에 듭니다.

다음 편에서는 방금 표로 훑은 컴포넌트들이 실제로 어떻게 맞물려 돌아가는지를 뜯어봅니다.

➡️ 다음 편: 1편 — Airflow 3 아키텍처 해부