이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.
- Airflow dependency, retry, SLA는 각각 어떤 운영 문제를 해결하는가?
- retry를 켜도 되는 task와 켜면 위험한 task는 어떻게 구분하는가?
- SLA miss는 task failure와 어떻게 다르고 왜 별도 알림이 필요한가?
- upstream 데이터 지연과 worker capacity 문제를 어떤 지표로 구분하는가?
개요
dependency는 task 실행 순서를 보장한다.
retry는 일시 오류를 다시 시도하게 한다.
SLA는 작업이 성공했더라도 약속한 시간보다 늦으면 운영 사건으로 보게 한다.
이 셋은 모두 실패 처리를 다루지만 의미가 다르다.
같은 알림으로 묶으면 장애 대응이 느려진다.
Dependency
dependency는 데이터 전제 조건을 표현한다.
extract_orders >> validate_orders >> build_mart >> publish_reportbuild_mart는 검증된 raw 데이터가 있어야 실행된다.
publish_report는 mart 품질 검증이 끝나야 실행된다.
dependency를 코드 밖 runbook으로만 관리하면 사람이 순서를 기억해야 한다.
Airflow DAG는 이 순서를 실행 가능한 문서로 만든다.
Retry
retry는 일시적인 실패에만 적합하다.
네트워크 timeout, 일시 DB connection 오류, object storage read timeout은 retry 대상이 될 수 있다.
schema mismatch, 잘못된 SQL, payload format 오류는 retry해도 성공하지 않는다.
retry를 무조건 늘리면 장애 감지가 늦어진다.
task가 retry되어도 안전하려면 idempotent해야 한다.
같은 task가 두 번 실행돼도 target 데이터가 중복되면 안 된다.
Retry 설정
@task(retries=3, retry_delay=timedelta(minutes=5))
def build_order_mart(ds=None):
run_batch("build-order-mart", target_date=ds)retry 횟수와 간격은 downstream SLA와 맞아야 한다.
3번 retry에 각 30분이 걸리면 아침 리포트 SLA를 이미 넘길 수 있다.
retry는 실패를 숨기는 장치가 아니라 복구 가능한 오류를 자동으로 흡수하는 장치다.
SLA Miss
SLA miss는 task가 실패했다는 뜻이 아니다.
성공했지만 늦었다는 뜻일 수 있다.
예를 들어 daily mart가 08:00까지 준비되어야 하는데 08:20에 성공하면 task state는 success여도 사용자 영향이 있다.
그래서 SLA miss는 별도 알림과 회고 대상이 된다.
SLA는 데이터 freshness 요구와 연결된다.
Upstream 지연과 Worker 문제
task가 늦어지는 이유는 다를 수 있다.
upstream 데이터가 늦게 도착했을 수 있다.
worker queue가 밀렸을 수 있다.
task 처리 시간이 늘었을 수 있다.
외부 API가 느릴 수 있다.
각 원인은 대응이 다르다.
Airflow 지표만 보지 말고 source freshness, queue time, task duration을 함께 본다.
알림 분리
알림은 최소 세 가지로 나눈다.
- task failure: 실행 실패
- retry exhausted: 자동 복구 실패
- SLA miss: 늦은 성공 또는 지연
품질 검증 실패는 네 번째 알림으로 분리할 수 있다.
모든 알림을 “DAG 실패”로 보내면 운영자가 원인을 다시 분류해야 한다.
실패 모델
- upstream dependency 없이 downstream report가 실행된다.
- retry 불가능한 schema 오류를 계속 retry한다.
- retry가 target table에 중복 row를 만든다.
- SLA miss를 task failure와 같은 severity로 보낸다.
- worker queue 지연을 source 데이터 지연으로 오해한다.
이 실패들은 운영 지표 분리가 없으면 반복된다.
운영 지표
- upstream wait time: dependency 대기 시간이다.
- task retry count: retry 빈도다.
- retry exhausted count: 자동 복구 실패다.
- task queue time: worker capacity 문제다.
- task duration: 처리 시간 변화다.
- SLA miss count: 늦은 완료다.
- data freshness lag: 데이터 최신성 지연이다.
SLA miss가 늘면 task failure보다 freshness와 queue time을 먼저 같이 본다.
개인 프로젝트 기준
개인 프로젝트에서는 실패하는 task 하나와 느린 task 하나를 만든다.
실패 task는 retry 후 성공하게 한다.
느린 task는 SLA miss를 발생시킨다.
두 알림을 분리해 기록하면 dependency/retry/SLA 차이를 설명할 수 있다.
위험 신호!
- 모든 task에 같은 retry 정책을 적용한다.
- retry해도 안전하지 않은 task에 retry를 켠다.
- SLA miss를 설정하지 않는다.
- DAG success만 보고 리포트 freshness를 보지 않는다.
- queue time과 task duration을 구분하지 않는다.
확인 질문
확인 질문
- 이 task 실패는 retry하면 성공할 가능성이 있는가?
- 일시 오류와 영구 오류를 구분해야 한다.
- 같은 task가 두 번 실행되어도 target 결과가 중복되지 않는가?
- retry를 켜기 전 idempotency가 필요하다.
- 성공했지만 늦은 경우 사용자에게 어떤 영향이 있는가?
- SLA miss와 data freshness 기준으로 답해야 한다.