[Airflow] DAG 처음 짜면서 했던 실수들

2026. 4. 14. 16:28·Airflow

1. 들어가며

Airflow를 처음 접했을 때 솔직히 이런 생각이 들었다.

"이거 그냥 cron이랑 뭐가 달라?"

Python으로 스케줄 짜고, 태스크 실행하고… 겉으로 보면 비슷해 보인다. 그런데 실제로 DAG를 짜기 시작하자마자 예상치 못한 곳에서 계속 막혔다.

이 글은 그 과정에서 내가 직접 겪었던 실수들을 정리한 기록이다. Airflow를 처음 시작하는 분들이 같은 곳에서 시간을 낭비하지 않았으면 하는 마음으로 썼다.


2. start_date를 datetime.now()로 설정했다

어떤 실수였나

DAG를 처음 만들 때 start_date를 이렇게 설정했다.

 
 
python
from datetime import datetime
from airflow import DAG

with DAG(
    dag_id="my_first_dag",
    start_date=datetime.now(),  # 이렇게 하면 안 된다
    schedule_interval="@daily",
) as dag:
    ...

언뜻 보면 "지금부터 시작"이라는 뜻이니까 자연스러워 보인다. 그런데 이걸 실행하면 DAG가 제대로 트리거되지 않거나, 매번 실행할 때마다 start_date가 달라지는 문제가 생긴다. 그렇게 되면 과거 시점이 존재하지 않게되어 catchup이 불가능해지는 문제도 있다.

왜 안 되는 걸까

Airflow는 DAG 파일을 주기적으로 파싱한다. 스케줄러가 DAG 파일을 읽을 때마다 datetime.now()가 새로 계산되기 때문에, start_date가 계속 바뀐다. Airflow 입장에서는 "언제부터 시작해야 하는지"를 일관되게 알 수 없게 되는 것이다.

 

올바른 방법

start_date는 항상 고정된 과거 날짜로 설정한다.

 
 
python
from datetime import datetime
from airflow import DAG

with DAG(
    dag_id="my_first_dag",
    start_date=datetime(2024, 1, 1),  # 고정된 과거 날짜
    schedule_interval="@daily",
) as dag:
    ...

3. catchup=True인 줄 몰랐다

어떤 실수였나

DAG를 처음 활성화했더니 갑자기 태스크가 수십 개씩 한꺼번에 실행되기 시작했다. "왜 이렇게 많이 돌아가지?" 하고 보니, Airflow가 start_date부터 현재까지 밀린 실행을 모두 메꾸려고 한 것이었다.

예를 들어 start_date를 6개월 전으로 설정하고 schedule_interval="@daily"로 하면, DAG를 활성화하는 순간 180개의 DAG Run이 한꺼번에 생성된다.

왜 이런 일이 생기나

Airflow에는 catchup이라는 설정이 있는데, 기본값이 True 다. catchup=True는 "과거에 실행됐어야 했는데 못 한 것들을 지금 다 채워라"라는 의미다.

처음엔 이 기본값의 존재 자체를 몰랐다.

올바른 방법

대부분의 경우, 특히 처음 개발할 때는 catchup=False로 설정하는 것이 안전하다.

 
 
python
with DAG(
    dag_id="my_first_dag",
    start_date=datetime(2024, 1, 1),
    schedule_interval="@daily",
    catchup=False,  # 과거 실행 채우지 않음
) as dag:
    ...

물론 catchup=True가 유용한 경우도 있다. 데이터 파이프라인에서 특정 날짜 범위의 데이터를 재처리해야 할 때는 의도적으로 True로 설정하기도 한다. 중요한 건 기본값이 True라는 것을 알고 명시적으로 선택하는 것이다.


4. Task가 실패해도 데이터가 중복됐다

어떤 실수였나

Task가 중간에 실패해서 재실행했더니 DB에 데이터가 두 번 들어가 있었다. "재실행하면 이전 결과가 덮어씌워지는 거 아닌가?" 하고 생각했는데, 전혀 그렇지 않았다.

 
 
python
def insert_data():
    # 단순 INSERT는 재실행 시 중복 발생
    db.execute("INSERT INTO orders SELECT * FROM raw_orders WHERE date = '2024-01-01'")

Task가 실패한 후 재실행하면, 이전에 이미 실행된 부분이 또 실행되면서 데이터가 쌓였다.

핵심 개념 - 멱등성(Idempotency)

이때 처음 알게 된 개념이 멱등성(Idempotency) 이다.

멱등성이란, 같은 작업을 몇 번 반복해도 결과가 동일한 성질을 말한다. Airflow에서 Task는 실패 시 재실행될 수 있기 때문에, Task 자체가 멱등해야 한다. 즉, "몇 번 실행해도 결과가 같아야 한다"는 원칙이다.

올바른 방법

단순 INSERT 대신 UPSERT나 삭제 후 재삽입 방식을 사용한다.

 
 
python
def insert_data():
    # 방법 1: UPSERT (PostgreSQL 기준)
    db.execute("""
        INSERT INTO orders SELECT * FROM raw_orders WHERE date = '2024-01-01'
        ON CONFLICT (id) DO UPDATE SET ...
    """)

def insert_data():
    # 방법 2: 해당 날짜 데이터 삭제 후 재삽입
    db.execute("DELETE FROM orders WHERE date = '2024-01-01'")
    db.execute("INSERT INTO orders SELECT * FROM raw_orders WHERE date = '2024-01-01'")

처음엔 "그냥 재실행 안 되게 잘 짜면 되지 않나?"라고 생각할 수 있다. 하지만 분산 환경에서 Task는 언제든 실패할 수 있고, Airflow는 그 상황에서도 파이프라인이 안전하게 재실행될 수 있도록 설계되어야 한다.


5. 마치며

지금 돌이켜보면 이 실수들은 다 "당연히 이렇게 되겠지"라는 막연한 가정에서 비롯됐다.

  • datetime.now()가 직관적으로 보였고,
  • catchup 같은 기본값의 존재를 몰랐고,
  • 재실행 시 멱등성이 보장돼야 한다는 개념 자체가 낯설었다.

Airflow는 단순히 스크립트를 스케줄링하는 도구가 아니라, 분산 환경에서 신뢰할 수 있는 데이터 파이프라인을 만들기 위한 도구다.

그 관점에서 다시 보면 위의 개념들이 왜 그렇게 설계됐는지 자연스럽게 이해된다.

 

다음엔 Airflow를 조금 더 써보면서 느낀 것들을 정리해볼 예정이다.

'Airflow' 카테고리의 다른 글

[Date Engineer] Data Firehose란?  (0) 2026.04.18
[Airflow] ec2를 사용해 클라우드에 airflow 띄우기 - (2. EC2 인스턴스에 docker 환경 구축하기)  (0) 2026.04.17
[Airflow] ec2를 사용해 클라우드에 airflow 띄우기 - (1. EC2 인스턴스 만들기)  (0) 2026.04.16
'Airflow' 카테고리의 다른 글
  • [Date Engineer] Data Firehose란?
  • [Airflow] ec2를 사용해 클라우드에 airflow 띄우기 - (2. EC2 인스턴스에 docker 환경 구축하기)
  • [Airflow] ec2를 사용해 클라우드에 airflow 띄우기 - (1. EC2 인스턴스 만들기)
byhy0
byhy0
byhy0 님의 블로그 입니다.
  • byhy0
    byhy0 님의 블로그
    byhy0
  • 전체
    오늘
    어제
    • 분류 전체보기 (62)
      • T아카데미 (4)
      • Project (2)
      • Airflow (4)
      • Python (16)
        • Django (0)
      • Java (1)
      • Spring (4)
        • Board Project (3)
      • SQL (3)
      • Docker (1)
      • 클라우드 (2)
      • Error (3)
      • Git (5)
      • 코딩테스트 (12)
        • SQL (5)
        • Python (7)
      • TIL (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    T아카데미 #2주차 회고 #데이터 엔지니어 2기
    BigQuery #SQL
    API 요청 #API
    venv #파이썬 가상환경 #가상환경
    python #pytest #테스트
    게시판
    #Python #정규표현식 #Regex #웹크롤링 #데이터처리
    vscode #git #git연동법
    programmers #SQL #코딩테스트
    Spring
    #클라우드 #클라우드컴퓨팅 #CloudComputing #온프레미스 #CS기초 #IT인프라 #서버
    programmers # 코딩테스트 #sql
    git #github #repository 생성
    티스토리챌린지
    T아카데미 #면접 #데이터 엔지니어 #K-Digital Traning
    push #pull #git연동
    T아카데미 #SK플래닛 #회고 #1주차
    T아카데미#SK플래닛#데이터엔지니어2기
    Git #설치법
    오블완
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
byhy0
[Airflow] DAG 처음 짜면서 했던 실수들
상단으로

티스토리툴바