Airflow, Prefect, Dagster — 데이터 파이프라인 오케스트레이션 도구 어떻게 고를까
Apache Airflow, Prefect, Dagster의 DAG 모델·상태 관리·장애 처리 방식을 비교하고, 조직 상황별 선택 기준과 운영 시 트레이드오프를 정리한다.
2026-08-12 · 최초 발행 2025-10-14
파이프라인이 하나둘 늘어나다 보면 언젠가 "이걸 크론으로 계속 돌릴 수는 없다"는 지점에 도달한다. 태스크 사이 의존성을 관리하고, 실패한 부분만 다시 돌리고, 어떤 작업이 언제 왜 실패했는지 추적할 수 있어야 한다. 이 문제를 푸는 도구가 오케스트레이터고, 지금 가장 많이 비교되는 세 가지가 Apache Airflow, Prefect, Dagster다. 셋 다 파이프라인을 DAG(방향 비순환 그래프)로 정의하고 스케줄링·재시도·관측성을 통합 관리한다는 점은 같지만, 그 DAG를 무엇으로 취급하느냐에서 철학이 갈린다.
태스크로 볼 것인가, 자산으로 볼 것인가
Airflow는 가장 오래됐고 가장 널리 쓰인다. 태스크 간 의존성과 순서를 명시적으로 정의하고, 이벤트 기반(센서·콜백)과 일정 기반(크론) 트리거를 함께 지원한다. Prefect는 Pythonic한 런타임을 지향해서 데코레이터 몇 개로 함수를 태스크·플로우로 승격시킬 수 있고, Dask나 Ray와 엮어 병렬 처리도 가능하다. Dagster는 관점 자체가 다르다 — 태스크를 실행 단위로 보는 대신 "소프트웨어 정의 자산(Software-Defined Asset)"이라는 개념으로 파이프라인이 만들어내는 산출물(테이블, 모델, 파일)을 1급 시민으로 취급하고, 그 신선도와 물질화(materialization) 여부를 추적한다.
이 차이는 상태 관리 방식에도 그대로 이어진다. Airflow는 메타데이터 DB에서 스케줄러·워커 간 레코드를 잠그고 Pool/Concurrency로 전역 동시성을 제어한다. Prefect는 API/서버가 상태 전이의 원자성을 보장하고, 워크 큐와 예약창으로 중복 실행을 막는다. Dagster는 Run/Asset 스토리지에 원자적으로 상태를 기록하고, 큐와 런 코디네이터로 단일 소비를 보장한다. 에러가 나면 셋 다 재시도·백오프·태스크 수준 온-페일 콜백으로 대응하고, 부분 성공 시에는 체크포인트·캐시를 활용해 실패한 태스크만 다시 돌린다.
실행 흐름은 결국 비슷하다
트리거(스케줄·이벤트·수동)로 시작해 DAG를 파싱하고 의존성을 정렬한 뒤 태스크를 큐에 넣고 워커가 실행, 결과를 상태 저장소에 반영하는 흐름 자체는 세 도구가 크게 다르지 않다.
실무에서는 어떻게 쓰이나
Airflow는 dbt·Snowflake·BigQuery와 묶어 배치 ETL/ELT 웨어하우스 파이프라인을 돌리는 조합으로 자주 쓰인다. 캐치업·백필로 과거 데이터를 자동으로 채우고, SLA 알림과 Pool로 서드파티 API의 레이트리밋을 보호하는 식이다. Prefect는 센서·워크 큐로 S3/GCS 업로드 같은 이벤트를 감지해 증분 적재를 트리거하는 데 강하고, 실패 시 부분 재처리와 결과 캐시로 비용을 아낀다. Dagster는 소프트웨어 정의 자산으로 피처·모델 아티팩트의 일관성을 보장하는 ML 파이프라인, 재학습·평가·프로모션 단계를 분리하고 신선도 SLA를 모니터링해야 하는 환경에 잘 맞는다. 데이터 품질 검증은 도구와 무관하게 Great Expectations나 Deequ를 검증 태스크로 끼워 넣고, 실패 시 다운스트림을 차단(데이터 게이팅)하거나 자동으로 티켓을 발행하는 패턴이 공통적으로 쓰인다.
최소 예제로 보는 API 철학
세 도구 모두 "추출 → 변환 → 적재"라는 같은 3단계를 어떻게 코드로 표현하는지 비교하면 감이 온다. Python 3.10+ 로컬 실행 기준이며, 버전별 세부 옵션은 도입 전 공식 문서로 확인해야 한다.
Apache Airflow 2.8+ (TaskFlow API)
# dags/etl_example.py
from datetime import datetime
from airflow.decorators import dag, task
@dag(schedule="@daily", start_date=datetime(2024, 1, 1), catchup=False, default_args={"retries": 2})
def etl_example():
@task
def extract():
return [1, 2, 3]
@task
def transform(data: list[int]):
return [x * 2 for x in data]
@task
def load(rows: list[int]):
# 멱등성 예: 대상 테이블에 날짜 파티션 업서트
print(f"Loaded: {rows}")
load(transform(extract()))
etl_example()
airflow db init && airflow webserver & airflow scheduler로 띄운 뒤 브라우저 UI에서 etl_example을 트리거한다.
Prefect 2.x
# prefect_flow.py
from prefect import flow, task
from datetime import timedelta
@task(retries=2, retry_delay_seconds=10)
def extract():
return [1, 2, 3]
@task
def transform(data):
return [x * 2 for x in data]
@task
def load(rows):
print(f"Loaded: {rows}")
@flow(name="etl_example")
def etl_flow():
load(transform(extract()))
if __name__ == "__main__":
etl_flow()
배포까지 하려면 prefect deployment build prefect_flow.py:etl_flow -n daily -q default -s "0 2 * * *" → prefect deployment apply etl_flow-deployment.yaml → prefect agent start -q default 순서로 진행한다.
Dagster 1.6+
# etl_job.py
from dagster import op, job, ScheduleDefinition, Definitions
@op
def extract():
return [1, 2, 3]
@op
def transform(context, data):
return [x * 2 for x in data]
@op
def load(context, rows):
context.log.info(f"Loaded: {rows}")
@job
def etl_job():
load(transform(extract()))
daily_schedule = ScheduleDefinition(job=etl_job, cron_schedule="0 2 * * *")
defs = Definitions(jobs=[etl_job], schedules=[daily_schedule])
dagit -m etl_job.py로 UI를 띄우고 거기서 etl_job을 실행하거나 스케줄을 활성화한다.
도구보다 먼저 갖춰야 할 것들
어떤 오케스트레이터를 쓰든 태스크 멱등성(업서트·검사합·스냅샷)을 확보하지 않으면 재시도 자체가 위험해진다. 지수 백오프, 데드레터 큐, 부분 재실행 전략은 세 도구 모두에서 별도로 설계해야 하는 부분이다. 시크릿은 Vault나 Secret Manager로 관리하고 환경 변수·평문 저장은 피해야 하며, 실행 컨테이너는 최소 권한으로, 네트워크 이그레스는 제한해야 한다. 관측성 측면에서는 대기·실행 시간, 성공률, SLA 위반 같은 표준 메트릭을 대시보드로 만들고 구조화 로그·분산 트레이싱을 갖추는 것이 도구 선택보다 먼저다. 메타DB(특히 Airflow)는 PostgreSQL 기반 HA 구성과 자동 백업·PITR을 갖춰야 하고, DAG·자산 변경은 코드 리뷰와 CI/CD를 거쳐 승인하는 거버넌스가 필요하다.
이런 기반을 갖추면 재시도·부분 재실행·캐시 활용으로 실패율이 3060% 감소하고 재처리 시간이 50% 이상 단축된다. 표준화·자동화로 운영 인건비는 2040%, 인프라 비용은 15~25% 낮아진다.
결론적으로 무엇을 고를까
광범위한 생태계와 엔터프라이즈 통합, 대규모 배치 중심 환경이라면 Airflow가 여전히 기본 선택지다. 빠른 도입과 개발자 경험, 매니지드 운영을 선호하는 조직은 Prefect가 부담이 적다. 자산 중심의 데이터 제품을 만들고 일관성·타입 안정성을 중시한다면 Dagster의 학습 곡선을 감수할 가치가 있다. 어느 쪽이든 파일럿 파이프라인 2~3개로 성능·운영성을 먼저 검증하고, 멱등성·관측성·보안 표준을 세운 뒤에 전사로 확산하고, CI/CD와 IaC(Terraform/Helm)로 재현 가능한 운영을 정착시키는 순서가 도구 자체의 선택보다 결과에 더 크게 기여한다.