문제 상황
우리가 만드는 서비스는 **“실시간에 가까운 트렌드 데이터”**를 수집해 키워드·기사·영상·LLM 요약으로 변환해서 사용자에게 전송한다. 하루 24 번, 한 달이면 720 배치를 돌려야 하는데, 각 단계마다 속도가 제각각이다.
- 한 번 호출에 200 ms인 Google Trends, 1 초쯤 걸리는 Naver News API
- 기사 20건을 붙여서 요청해서 Summary를 생성해야 하는 LLM API(최대 15 초)
- 장애가 터지면 지난 몇시간의 데이터을 다시 긁어 와야 하고, 운영팀은 성공·실패 알람을 한 곳에서 받고 싶어 했다.
간단한 cron 잡으로도 시작할 수 있었지만, 이렇게 복잡해지는 워크플로를 사람이 손으로 리런(re‑run)하다 보면 금세 지옥이 된다. 그래서 “워크플로를 코드로 관리하면서 재시도·백필·모니터링까지 제공하는 툴”을 찾기 시작했다.
제안
여러 후보를 비교한 결과, Apache Airflow 2.8를 도입하기로 했다.
- 표현력
- Python DAG 한 파일로 Branch, SLA, Retry, Backfill, 동적 Task 생성까지 기술할 수 있어 외부 API ↔ Kafka 토픽 같은 이질적인 단계를 자연스럽게 묶을 수 있다.
- 비용 = 0 라이선스 + 저렴한 인프라
- 오픈 소스라 소프트웨어 비용이 없고, EKS Spot 워크 노드 기준 시간당 < $0.05 안에서 스케줄러·워커를 굴린다. 동일 DAG를 AWS Step Functions로 옮기면 한 달에 $200 이상이 든다.
- 생태계·미래 호환
- 90 개 넘는 Provider 패키지, Helm Chart, Terraform 모듈이 다 준비돼 있다.
- 팀 역량 Fit
- 한 달이라는 충분한 작업기간이 주어져있으며 백엔드에 이미 개념을 학습한 팀원이 있다.
장단점
장점
- DAG 그래프 UI로 의존·성공·실패 상태를 한눈에 본다 → 야간 장애 대응 속도가 빨라진다.
- airflow dags backfill --start-date 20250420 --end-date 20250422로 이틀치 데이터를 다시 생산할 수 있다.
- SLA Miss, Task Retry Failure를 Slack·PagerDuty에 자동 전송해 운영 가시성이 높다.
단점 & 리스크
- 스케줄러·워커·메타DB 세 구성요소를 우리가 직접 운영해야 한다. Helm 업그레이드, DB 백업·마이그레이션 정책이 필수다.
- 워커 컨테이너 부팅 지연(수 초) 때문에 밀리초 레이턴시 요구에는 맞지 않는다.
- Python 코드 리뷰·테스트로 인해 언어 장벽이 생길 수 있다.
완화책 : Blue‑Green Helm 업데이트, RDS Multi‑AZ, DAG Test CI 파이프라인, 필요시 TriggerDagRunOperator로 초단위 이벤트를 Kafka Streams에 위임.
대안
대안 매력 포인트 우리 프로젝트와 맞지 않은 이유
Spring Boot @Scheduled + cron | 팀이 Spring Boot를 이미 쓰고, 추가 비용 0원. | DAG 시각화·재시도·백필 기능이 없다. API 지연이 애플리케이션 스레드를 막아 서비스 품질에 영향. |
Kafka Streams windowedBy(Duration.ofHours(1)) | 스트림 안에서 집계까지 끝, 코드 단일화. | 외부 REST API 호출, LLM 요약처럼 스트림 밖 사이드 이펙트를 모델링하기 어렵다. 윈도 고정이라 과거 6 시간을 **다시 돌리기(backfill)**가 까다롭다. |
AWS Step Functions | 완전 관리형, UI 좋음. | State 전환당 $0.025 → 우리 DAG(1,200 state/hour) = 월 $200↑, 예산 초과. JSON DSL 문법이 장황해 복잡 DAG 작성 피로도. |
최종 채택 및 차후 과제
- Airflow 채택 시점운영에 들어가면 팀 위키에 DAG 작성 규칙과 장애 대응 플로우를 문서화한다. 비용은 CloudWatch 대시보드로 모니터링해 점검할 예정이다.
- Airflow를 바로 프로덕션에 들이기보다는 **작은 증명(PoC)**부터 시작한다. 개발용 EKS 클러스터에 Airflow를 올리고, 1시간짜리 hourly_ingest DAG를 실행해 본다. 성공·실패 알람이 Slack으로 잘 오는지 확인한 뒤, Helm 설정 값을 고정하고 KEDA 오토스케일러로 워크 노드를 늘였다 줄였다 할 계획이다.
- 채택
- Spring Boot Batch
- 차후 과제
- 파이프라인 구현
'kkokkio - 프로젝트 > ADR(의사결정문서)' 카테고리의 다른 글
Prometheus + Grafana (0) | 2025.06.11 |
---|---|
Spring Batch (0) | 2025.06.11 |
Flyway (1) | 2025.06.11 |
Swagger (0) | 2025.06.11 |
MySQL (0) | 2025.06.11 |