> ## Documentation Index
> Fetch the complete documentation index at: https://0x38a.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 0x05. Airflow 3.0 - 5년 만의 메이저 업데이트, 무엇이 바뀌었나

> Task SDK, Asset 기반 스케줄링, DAG 버전 관리, React UI까지 Airflow 3.0의 핵심 변화를 정리한다.

2025년 4월, Apache Airflow 3.0이 정식 출시되었다. Airflow 2.0 이후 **5년 만의 메이저 릴리스**이다. 단순한 기능 추가가 아니라, 아키텍처 수준에서 근본적인 변화가 이루어졌다. Task 실행 방식, 스케줄링 패러다임, UI, 보안 모델 모두 달라졌다.

이 글에서는 Airflow 3.0의 핵심 변화를 기존 2.x와 비교하며 정리한다.

***

## 1. Task SDK — 태스크 실행의 분리

Airflow 3.0의 가장 근본적인 변화이다. 기존에는 Worker가 Airflow의 전체 코드베이스를 로드해야 태스크를 실행할 수 있었다. 3.0에서는 **Task SDK**라는 경량 런타임을 도입하여 태스크 실행을 오케스트레이터로부터 분리했다.

### Airflow 2.x

```
Worker 프로세스
├── Airflow 전체 코드베이스 로드
├── 메타데이터 DB 직접 접근
└── 태스크 실행
```

Worker가 메타데이터 DB에 직접 접근했다. 보안 경계가 모호하고, Worker가 DB 커넥션 정보를 가지고 있어야 했다.

### Airflow 3.0

```
Task SDK (경량 런타임)
├── Task Execution API를 통해서만 통신
├── DB 직접 접근 불가
└── 컨테이너, 엣지, 원격 환경에서 실행 가능
```

Task SDK는 **Task Execution API**를 통해서만 Airflow와 통신한다. DB 접근이 차단되어 보안이 강화되고, 컨테이너나 원격 환경에서 격리된 상태로 실행할 수 있다.

<figure>
  <img src="https://mintcdn.com/0x38a/g-1hLDU267VcSxbl/images/blog/airflow/airflow_architecture.png?fit=max&auto=format&n=g-1hLDU267VcSxbl&q=85&s=bdf9fa07e7ff27366f07eaf852bc8993" alt="Airflow 3.0 architecture" width="700" data-path="images/blog/airflow/airflow_architecture.png" />
</figure>

### 새로운 import 경로

```python theme={null}
# Airflow 2.x
from airflow.decorators import dag, task
from airflow import DAG

# Airflow 3.0
from airflow.sdk import dag, task, DAG
```

`airflow.sdk` 네임스페이스로 DAG 작성에 필요한 인터페이스가 통합되었다. 기존 import도 당분간 호환되지만, 새 프로젝트에서는 `airflow.sdk`를 사용해야 한다.

### 멀티 언어 지원 (로드맵)

Task SDK의 아키텍처는 Python 외의 언어도 지원할 수 있도록 설계되었다. 3.0 출시 시점에는 Python만 지원하지만, Java, Go, R 등의 SDK가 로드맵에 있다. Task Execution API가 언어 중립적인 HTTP/gRPC 인터페이스이기 때문에 가능한 구조이다.

***

## 2. Asset 기반 스케줄링

Airflow 2.x에서 Dataset이라 불리던 기능이 3.0에서 **Asset**으로 재설계되었다. 단순히 이름만 바뀐 것이 아니라, `@asset` 데코레이터와 이벤트 드리븐 스케줄링이 추가되었다.

### @asset 데코레이터

```python theme={null}
from airflow.sdk import asset

@asset(uri="s3://my-bucket/customer-data.csv", schedule="@daily")
def customer_data():
    """고객 데이터를 처리한다."""
    # S3에서 데이터 읽기 → 변환 → 저장
    ...
```

`@asset` 데코레이터는 함수 하나로 세 가지를 자동 생성한다:

* **Asset** (데이터 자산 정의)
* **DAG** (같은 이름의 DAG)
* **Task** (Asset을 생산하는 태스크)

Dagster의 Software-Defined Assets에서 영감을 받은 접근이다.

### 조건부 Asset 스케줄링

```python theme={null}
from airflow.sdk import DAG, AssetAll, AssetAny

# orders AND payments가 모두 업데이트되면 실행
with DAG(
    dag_id="process_orders",
    schedule=AssetAll("orders", "payments"),
):
    ...

# orders OR payments 중 하나라도 업데이트되면 실행
with DAG(
    dag_id="monitor_updates",
    schedule=AssetAny("orders", "payments"),
):
    ...
```

`AssetAll`(AND), `AssetAny`(OR)로 복잡한 의존성을 선언적으로 표현할 수 있다. 2.x에서는 단순한 Dataset 트리거만 가능했다.

### AssetWatcher — 외부 이벤트 감시

```python theme={null}
from airflow.sdk import Asset, AssetWatcher

customer_asset = Asset(
    uri="s3://bucket/customers.csv",
    watchers=[
        AssetWatcher(source="sqs://my-queue")
    ],
)
```

**AssetWatcher**는 외부 이벤트 소스(SQS, Kafka 등)를 감시하여 Asset 업데이트를 트리거한다. Cron 기반 폴링 없이 **진정한 이벤트 드리븐 스케줄링**이 가능해졌다.

***

## 3. DAG Versioning

"지난주에 실행된 DAG가 지금과 같은 코드인가?" — Airflow 2.x에서는 답하기 어려운 질문이었다. DAG 파일을 업데이트하면 이전 버전이 사라졌다.

Airflow 3.0은 **DAG 버전을 자동으로 추적**한다.

* DAG 구조가 변경될 때마다 새 버전이 생성된다
* 각 DAG Run은 **실행 시점의 DAG 버전에 고정**된다. 실행 중에 새 버전이 업로드되어도 기존 Run은 원래 버전으로 완료된다
* UI와 API에서 **과거 버전의 DAG 정의를 조회**할 수 있다

Git 커밋처럼 "이 시점에 어떤 코드가 실행되었는지" 감사 추적(audit trail)이 가능해졌다.

***

## 4. React UI

Flask-Admin 기반의 레거시 UI가 **React + FastAPI** 기반으로 완전 재작성되었다.

<figure>
  <img src="https://mintcdn.com/0x38a/g-1hLDU267VcSxbl/images/blog/airflow/airflow_ui.png?fit=max&auto=format&n=g-1hLDU267VcSxbl&q=85&s=d7b46117315a296728031a8753f7014d" alt="Airflow 3.0 React UI" width="700" data-path="images/blog/airflow/airflow_ui.png" />
</figure>

### 주요 개선

* **성능**: DAG가 수천 개여도 빠르게 로드
* **다크 모드**: 드디어 지원
* **DAG 즐겨찾기/핀**: 자주 사용하는 DAG를 상단에 고정
* **백필 관리**: UI에서 직접 백필 생성·모니터링·중지
* **다국어**: 17개 언어 지원
* **Calendar/Gantt 뷰 재설계**: 더 직관적인 시각화

***

## 5. Backfill 관리 개선

Airflow 2.x에서 백필은 CLI로만 실행할 수 있었고, 스케줄러와 별개로 동작했다.

```bash theme={null}
# Airflow 2.x
airflow dags backfill -s 2026-01-01 -e 2026-01-31 my_dag
```

3.0에서는 백필이 **스케줄러에 통합**되었다:

* **UI/API/CLI** 모든 경로에서 백필 실행 가능
* **비동기 실행**: 여러 백필을 동시에 큐잉
* **진행 상황 추적**: UI에서 태스크 단위 상태, 실시간 로그 확인
* **일시 중지/중단**: UI에서 직접 제어

***

## 6. Edge Executor

**Edge Executor**가 GA(Generally Available)로 승격되었다. 원격/분산 환경에서 태스크를 실행할 수 있다.

* 클라우드와 온프레미스를 넘나드는 **하이브리드 실행**
* IoT, 엣지 컴퓨팅 환경에서 태스크 실행
* 네트워크 경계를 넘는 **크로스 환경 오케스트레이션**

Task SDK + Edge Executor 조합으로 "오케스트레이션은 중앙, 실행은 분산" 패턴이 자연스러워졌다.

***

## 7. 조건부 태스크 실행

```python theme={null}
from airflow.sdk import task

@task.skip_if(lambda context: context["params"].get("skip_validation"))
def validate_data():
    ...

@task.run_if(lambda context: context["params"].get("include_report"))
def generate_report():
    ...
```

`@task.skip_if`와 `@task.run_if` 데코레이터로 태스크의 실행 조건을 선언적으로 정의할 수 있다. 2.x에서 BranchOperator나 ShortCircuitOperator로 복잡하게 구현하던 패턴이 한 줄로 줄어든다.

***

## 8. 제거된 기능

Airflow 2.x에서 deprecated 되었던 기능들이 3.0에서 공식 제거되었다.

| 제거된 기능                          | 대체                    |
| ------------------------------- | --------------------- |
| **SubDAG**                      | TaskGroup, Asset 스케줄링 |
| **SequentialExecutor**          | LocalExecutor         |
| **CeleryKubernetesExecutor**    | Multiple Executor 설정  |
| **SLA**                         | Deadline Alerts (로드맵) |
| `execution_date`                | `logical_date`        |
| `tomorrow_ds`, `yesterday_ds` 등 | 제거 (직접 계산)            |

가장 큰 영향을 주는 것은 **`execution_date` 제거**이다. 2.x에서 광범위하게 사용되던 이 변수가 `logical_date`로 완전히 대체되었다. 기존 DAG에서 `execution_date`를 사용하고 있다면 마이그레이션이 필요하다.

***

## 마이그레이션 가이드

### 사전 조건

* Airflow **2.7 이상**에서 업그레이드
* Python 3.9 \~ 3.12
* 메타데이터 DB **백업 필수**

### 업그레이드 점검 도구

```bash theme={null}
# Ruff 린터의 AIR 규칙으로 호환성 점검
ruff check --select AIR301,AIR302 dags/
```

* `AIR301`: 3.0에서 제거된 기능 사용
* `AIR302`: 3.0에서 변경된 기능 사용

### 주요 마이그레이션 포인트

1. **import 경로**: `from airflow.sdk import ...`로 전환
2. **`execution_date` → `logical_date`**: 모든 DAG에서 변경
3. **DB 직접 접근 제거**: 커스텀 Operator에서 `session.query()` 등 제거
4. **SubDAG → TaskGroup**: SubDAG를 사용하고 있다면 TaskGroup으로 리팩토링
5. **Dataset → Asset**: `Dataset` 클래스를 `Asset`으로 변경

***

## 핵심 정리

Airflow 3.0은 "Cron의 진화"에서 **현대적 오케스트레이션 플랫폼**으로의 전환이다.

* **Task SDK**: 태스크 실행을 오케스트레이터에서 분리. 보안 강화, 원격 실행, 멀티 언어 로드맵
* **Asset 스케줄링**: Cron 기반에서 데이터/이벤트 기반으로. `@asset` 데코레이터, `AssetAll`/`AssetAny`, `AssetWatcher`
* **DAG Versioning**: 실행 이력과 코드 버전의 연결. 감사 추적 가능
* **React UI**: 성능, 다크 모드, 백필 관리, 다국어
* **Edge Executor**: 하이브리드/크로스 환경 실행

Dagster의 Asset 중심 접근, Prefect의 Python-native 경험에 영향을 받으면서도, Airflow의 강점인 **거대한 생태계(2,000+ Providers)** 와 **검증된 프로덕션 안정성** 위에 현대적 기능을 쌓았다. 이미 Airflow를 사용하고 있다면 3.0 업그레이드는 충분히 가치 있다.

## 참고 자료

* [Apache Airflow 3 is Here!](https://airflow.apache.org/blog/airflow-three-point-oh-is-here/)
* [Upgrading to Airflow 3](https://airflow.apache.org/docs/apache-airflow/3.0.0/installation/upgrading_to_airflow3.html)
* [Airflow 3.0 Release Notes](https://airflow.apache.org/docs/apache-airflow/3.0.0/release_notes.html)
* [Asset-Aware Scheduling](https://airflow.apache.org/docs/apache-airflow/stable/authoring-and-scheduling/asset-scheduling.html)
* [Task SDK Documentation](https://airflow.apache.org/docs/task-sdk/stable/)
