데이터 파이프라인
데이터 파이프라인
외부 데이터를 다루는 시스템은 어디든 비슷한 단계로 환원됩니다. 데이터를 가져오고, 다듬고, 저장하고, 노출합니다.
1. ETL 과 ELT
| 약어 | 풀이 | 흐름 |
|---|---|---|
| ETL | Extract → Transform → Load | 데이터 웨어하우스에 적재하기 전에 변환 |
| ELT | Extract → Load → Transform | 일단 적재하고 웨어하우스 안에서 변환 |
ETL 은 1970~80 년대 데이터 웨어하우스 도입과 함께 등장한 용어입니다. 이 시기에는 저장 비용이 비싸 로드 전 정제가 합리적이었습니다. 2010 년대 이후 클라우드 웨어하우스 (Snowflake · BigQuery · Redshift) 의 저장·연산 비용 감소와 함께 ELT 패턴이 널리 퍼졌습니다. dbt (data build tool, 2016) 가 ELT 의 변환 단계를 SQL 로 구조화하면서 보편화했습니다.
선택 기준:
- 원자료를 그대로 보존할 가치가 있는가 (ELT 가 유리).
- 변환이 SQL 로 표현 가능한가 (ELT).
- 적재 전에 PII 를 마스킹해야 하는가 (ETL).
- 웨어하우스의 연산 비용이 변환 비용을 감당하는가 (ELT).
2. 4 단계 일반화
외부 데이터 흐름은 크게 네 단계로 나뉩니다.
① 수집 (Extract) API · 파일 · 크롤링 · CDC
② 정제 (Transform) 형식 변환 · 결측·이상치 · 정규화 · 중복 제거
③ 적재 (Load) 운영 DB · 데이터 레이크 · 웨어하우스
④ 노출 (Serve) API · 검색 · 대시보드 · 추천
각 단계 사이에 검증·관측·재시도가 들어갑니다. 단계마다 실패 모드가 다르므로 책임이 한 곳에 몰리지 않게 분리하는 편이 안전합니다.
3. 직접 호출 vs 큐 기반
직접 호출 (synchronous) — 수집 → 정제 → 적재가 한 프로세스에서 순차 실행됩니다. 단순하고 디버깅이 쉽습니다. 한계는 한 단계의 지연이 전체를 막고 외부 API 의 변동에 시스템이 묶인다는 점입니다.
큐 기반 (asynchronous) — 각 단계 사이에 큐 (Kafka · SQS · RabbitMQ · Redis Streams) 를 둡니다.
[Extractor] → topic.raw → [Transformer] → topic.clean → [Loader]
장점:
- 단계별 독립 배포·확장.
- 재처리 (replay) 가 가능 — 토픽에서 다시 읽습니다.
- 폭발적 트래픽 흡수.
한계:
- 운영 복잡도 증가.
- 메시지 순서·중복·지연의 가정이 명시적이어야 합니다.
선택은 데이터 양·실시간성 요구·팀 규모에 따릅니다.
4. 멱등성과 전달 보증
분산 시스템에서 메시지 전달의 의미는 셋입니다.
| 보증 | 의미 |
|---|---|
| at-most-once | 한 번 또는 0 번. 손실 가능. |
| at-least-once | 최소 한 번. 중복 가능. |
| exactly-once | 정확히 한 번. 구현 비용이 크고 가정의 범위를 좁혀야 성립. |
대부분의 큐는 at-least-once 를 기본 보증합니다. 따라서 컨슈머가 멱등 해야 한다는 약속이 따라옵니다. 같은 메시지를 두 번 처리해도 결과가 같도록 만듭니다.
멱등성을 얻는 흔한 방법:
- 자연 키 (외부 시스템의 고유 ID) 를 PK 로 활용 →
INSERT ... ON CONFLICT DO NOTHING. - 메시지에 idempotency key 를 부여 → 처리 기록 테이블로 중복 차단.
- upsert 패턴 → 두 번 적용해도 결과 동일.
Kafka 의 transactional producer · idempotent producer 옵션은 producer 측의 중복을 줄입니다 (완전한 exactly-once 는 토픽 안에서만 성립). kafka-when 에서 더 다룹니다.
5. 오케스트레이션 도구
여러 단계를 시각화하고 스케줄·재시도·의존성을 묶는 도구들이 있습니다.
Apache Airflow (2014, Airbnb) — 가장 널리 쓰이는 워크플로 도구입니다. DAG (Directed Acyclic Graph) 를 Python 코드로 정의합니다. 풍부한 operator (Hive · Spark · S3 · BigQuery 등) 와 큰 커뮤니티가 강점입니다. 한계는 스케줄러의 무게·동적 워크플로의 어색함입니다.
Dagster (2018) — 자산 (asset) 중심 모델. "어떤 데이터를 만들 것인가" 를 주제로 둡니다. 타입·테스트·관측이 더 정돈된 구조라는 평이 많습니다.
Prefect (2019) — Pythonic API 와 dynamic flow 가 특징. Airflow 보다 코드와 가까운 흐름을 강조합니다. 클라우드 호스팅 옵션도 있습니다.
Mage (2022) — 데이터 파이프라인을 노트북·블록 단위로 다룹니다. UI 친화적인 점이 특징입니다.
도구 선택의 기준은 팀 규모·기존 인프라·실시간성·관측 요구입니다. 단순한 cron + 스크립트로 충분한 자리도 많습니다.
6. 원본 보존과 가공 분리
원자료(raw) 와 가공 (clean/curated) 스키마를 분리합니다. 원본은 변경 없이 보관하고 변환 결과는 따로 만듭니다. 변환 로직이 바뀌면 원본을 다시 처리해 결과를 갱신합니다 (재현성).
7. CDC · 백필 · 데이터 품질
CDC (Change Data Capture) — 운영 DB 의 변경 (WAL · binlog) 을 추출해 다른 시스템에 흘려 보냅니다. Debezium 이 자주 거론됩니다. 폴링보다 부하·지연이 작습니다.
백필 (backfill) — 새 변환 로직을 과거 데이터에 적용하는 작업입니다. 큐 기반 파이프라인에서는 토픽 끝에서 처음으로 다시 읽거나, 스토리지에서 시작 시점을 지정해 재처리합니다.
데이터 품질 — great_expectations (2018) · dbt tests · Soda 같은 도구가 검증 단계를 코드화합니다. "행 수가 평소보다 30% 적으면 알람" 같은 규칙을 사람 손이 아닌 시스템이 봅니다.
8. 자주 걸리는 자리
외부 API 의 사일런트 변경 — 응답 스키마가 슬며시 바뀌면 적재된 데이터의 형이 깨집니다. 스키마 검증을 적재 직전에 둡니다.
시간대 가정 불일치 — 외부 시스템의 시각이 KST 인지 UTC 인지 모호하면 집계가 어긋납니다. 적재 시점에 UTC 로 통일하는 편이 안전합니다.
중복 적재 — 같은 ID 로 두 번 들어오면 카운트·집계가 부풀어 오릅니다. 자연 키 PK · upsert 로 차단합니다.
재처리의 부작용 — 백필이 실시간 통계와 섞여 사용자에게 일시적 불일치가 보일 수 있습니다. 적재와 노출 사이의 게이트 (예: 마테리얼라이즈드 뷰 갱신) 가 도움이 됩니다.
스케줄러의 단일 장애점 — 한 노드의 cron 이 장애나면 전체 파이프라인이 멈춥니다. 여러 워커 + 잠금 (분산 lock) 또는 매니지드 스케줄러를 검토합니다.
하고픈 말
데이터 파이프라인은 단계만 분리하면 운영이 절반 쉬워집니다. 어디서 데이터가 어그러졌는지 단계별로 보면 추적이 가능합니다. 도구는 일단 cron + Python 스크립트로 시작해도 됩니다. 기록·재현성만 챙겨 두면 도구는 나중에 갈아 끼울 수 있습니다.
Next
- kafka-when
- pgvector-rag
Apache Airflow 공식 · Dagster 공식 · Prefect 공식 · dbt 공식 · Debezium 공식 · Designing Data-Intensive Applications 을 참고합니다.