태스크/에셋 상태 저장소 정리 (가비지 컬렉션 운영)
Apache Airflow Official Documentation (in-repo snapshot) — Apache Software Foundation administration-and-deployment/task-and-asset-state-store-cleanup.rst (전체)
이 모듈을 다 읽으면
- airflow state-store clean 명령이 무엇을 삭제하고 무엇을 건드리지 않는지 설명할 수 있다
- retention 설정별로 expires_at이 어떻게 계산되는지 판단할 수 있다
- 배치 크기 설정이 필요한 상황과 정리 주기를 어떻게 정할지 설명할 수 있다
Airflow는 태스크 상태 저장소 행을 스케줄에 따라 자동으로 정리하지 않는다. 정리(가비지 컬렉션)는 사용자가 CLI로 명시적으로 트리거해야 하는 책임이며, 이 모듈은 무엇이 정리 대상인지, retention 설정별 expires_at 계산 규칙, 드라이런/배치 옵션, 정리 주기를 정하는 기준을 다룬다. (versionadded 3.3)
정리 대상과 책임 소재
Airflow는 태스크 상태 저장소 행을 스케줄에 따라 자동으로 삭제하지 않는다. 정리("가비지 컬렉션")는 사용자의 책임이며 CLI를 통해 명시적으로 트리거해야 한다.
정리 명령은 오직 ``MetastoreBackend``에 있는 **태스크 상태 저장소** 행에만 동작한다. 에셋 저장소 행은 이 명령이 절대 건드리지 않는다 — 에셋 저장소 행은 에셋이 비활성화될 때의 고아 스윕(orphan sweep)을 통해서만 제거된다(별도 메커니즘, task-and-asset-state-store 문서 참고).
핵심 포인트
- Airflow는 상태 저장소 행을 자동으로 정리하지 않으며, 정리는 CLI로 명시적으로 트리거해야 하는 사용자 책임이다
- 정리 명령은 MetastoreBackend의 태스크 상태 저장소 행만 대상으로 하며 에셋 저장소 행은 절대 건드리지 않는다
- 에셋 저장소 행은 에셋 비활성화 시의 고아 스윕이라는 별도 메커니즘으로만 제거된다
삭제 대상 판정 규칙 (expires_at)
태스크 상태 저장소 행은 ``expires_at`` 타임스탬프가 과거일 때 삭제 대상이 된다. ``expires_at``은 워커에서 쓰기 시점에 계산된다. 명시적으로 ``retention=timedelta(...)``를 지정해 쓴 키는 쓰기 시점으로부터 그 기간 뒤에 만료된다. ``retention=None``(기본값)으로 쓴 키는 ``[state_store] default_retention_days`` 기반의 만료 시점을 받는다 — 이 값이 0보다 크면 쓰기로부터 그만큼의 일수 뒤에 만료된다. ``retention=NEVER_EXPIRE``로 쓴 키는 ``expires_at = NULL``과 영구 표시 플래그를 가지며, 설정과 무관하게 이 명령으로 **절대** 삭제되지 않는다.
``[state_store] default_retention_days = 0``이면, 명시적 retention 없이 쓰인 키는 ``expires_at = NULL``(만료 없음)을 가지며 이 역시 건너뛰어진다. 오직 non-null이면서 과거인 ``expires_at``을 가진 행만 제거된다.
커스텀 백엔드(``[state_store] backend``가 기본값이 아닌 경우)는 명시적으로 건너뛰어진다. 정리 명령은 메시지를 출력하고 아무것도 삭제하지 않은 채 깔끔하게 종료된다. 커스텀 백엔드가 자체 retention 로직이 필요하다면 ``BaseStoreBackend.cleanup()``에 구현해 자체 유지보수 프로세스에서 호출해야 한다.
핵심 포인트
- expires_at은 워커에서 쓰기 시점에 계산되며 retention 종류(명시적 timedelta / None+default_retention_days / NEVER_EXPIRE)에 따라 다르게 결정된다
- default_retention_days=0이면 명시적 retention 없는 키는 expires_at=NULL로 만료 없음 처리되어 이 역시 건너뛰어진다
- 커스텀 백엔드는 명시적으로 건너뛰어지며, 자체 retention이 필요하면 BaseStoreBackend.cleanup()을 직접 구현해야 한다
정리 명령 실행: 드라이런과 배치
명령은 ``airflow state-store clean``이다. 이 명령은 ``airflow.cfg``에서 ``[state_store] default_retention_days``와 ``state_cleanup_batch_size``를 읽은 뒤 대상 행을 삭제한다.
``--dry-run``을 쓰면 실제로 아무것도 지우지 않고 무엇이 삭제될지 미리 볼 수 있다: ``airflow state-store clean --dry-run``. 출력에는 삭제될 모든 행이 dag, run, task, map index, key별로 그룹핑되어 나열된다.
배치 처리: 기본값(``state_cleanup_batch_size = 0``)에서는 대상 행 전체를 단일 statement로 삭제한다. ``task_state_store`` 테이블이 큰 배포에서는 트랜잭션당 락 시간을 줄이기 위해 배치 크기를 설정할 수 있다(예: 10000). 이 경우 명령은 각 배치를 커밋하며 대상 행이 남지 않을 때까지 10,000개 단위로 삭제를 반복한다.
핵심 포인트
- airflow state-store clean --dry-run으로 실제 삭제 없이 대상 행을 dag/run/task/map_index/key별로 미리 확인할 수 있다
- state_cleanup_batch_size=0(기본)은 단일 statement로 전체 삭제, 값을 주면 그 크기만큼 배치 커밋을 반복해 락 시간을 줄인다
정리 주기 결정
정리를 얼마나 자주 실행해야 하는지는 쓰기 볼륨과 ``default_retention_days`` 값에 달려 있다. 대부분의 환경에서는 주 1회 정리로 충분할 수 있다. 태스크 실행마다 상태 저장소 항목을 쓰는 고처리량 파이프라인이라면 ``task_state_store`` 테이블을 작게 유지하기 위해 더 자주 정리를 실행하는 것을 고려해야 한다.
핵심 포인트
- 정리 주기는 쓰기 볼륨과 default_retention_days에 따라 결정하며, 대부분은 주 1회로 충분하다
- 태스크 실행마다 상태를 쓰는 고처리량 파이프라인은 테이블 크기 관리를 위해 더 자주 정리해야 한다