학습 목표
bounded·unbounded 데이터를 구분하고 처리 모델을 맞출 수 있다.
배치·스트림 파이프라인의 수집·처리·출력 차이를 설명할 수 있다.
latency와 throughput 트레이드오프로 도구·스케줄을 선택할 수 있다.
리포트·알림·학습·재처리 등 use case에 맞는 쪽을 고를 수 있다.
문제 상황
- 야간 전체
SELECT는 잘 되는데 — 5분 안 이상 징후를 잡아야 함 - Kafka에 실시간 넣었지만 어제 데이터와 합쳐 feature table을 만들어야 함 — 경로가 둘로 갈라짐
- “스트리밍이 최신”이라 Spark Streaming만 썼더니 — 일일 리포트·backfill이 더 비쌈
- micro-batch 1분인데 SLA는 10초 — 진짜 스트림인지 배치인지 구분 못 함
- CDC는 unbounded인데 downstream은 일 단위 parquet — 어디서 경계를 자를지 모름
- 앞 편에서 velocity가 크면 ingest가 필요하다고 했지만 — 처리도 배치·스트림이 갈림
이번 편은 데이터 경계와 처리 모델 — 언제 배치, 언제 스트림, 둘 다일 때 어떻게 나누는지다. Kafka·Spark 구체는 다음 편부터.
1. Bounded vs Unbounded
처리 방식은 먼저 데이터 집합에 끝이 있는가로 나뉜다.

| Bounded | Unbounded | |
|---|---|---|
| 정의 | 유한·고정 입력 | 끝 없이 계속 들어옴 |
| 예 | 어제 export 파일, 스냅샷 테이블 | 앱 이벤트, CDC, 센서 |
| 처리 | 한 번 읽고 완료 | 상시 실행·윈도우로 자름 |
Bounded — S3 orders/2026-07-20/*.parquet (파일 목록이 닫힘)
Unbounded — topic orders.events (retention 전까지 계속 append)
- 같은 비즈니스라도 bounded 뷰를 만들 수 있음 — “어제 00:00~24:00 구간”은 배치 job 입력
- Unbounded를 다루려면 — buffer(Kafka), event time, watermark (Structured Streaming 편)
- Database CDC — 소스는 unbounded, warehouse 적재는 일·시간 bounded slice로 자르는 패턴이 흔함
- Variety·품질 검사 — bounded 샘플로 먼저, 스트림은 스키마·계약이 더 중요
2. 배치 처리 모델
모은 뒤 한꺼번에 처리한다. 입력이 닫힌 뒤 결과가 나온다.

| 단계 | 역할 |
|---|---|
| Collect | 기간·파일·스냅샷 경계 확정 |
| Store | raw layer (immutable) |
| Process | Spark batch, SQL, dbt |
| Publish | warehouse table, report, training set |
00:30 cron — ingest yesterday raw
02:00 — Spark job: aggregate by user_day
06:00 — BI dashboard refresh (T+1)
- 장점 — 높은 throughput, 재실행·backfill 단순, 비용 예측 쉬움
- 한계 — latency 분
시간일 — “지금” 질문에는 부적합 - 적합 — 일·주 리포트, ML 학습 데이터셋, 규제 월간 집계, 대량 join
- 앞 편 process 레이어의 야간 ETL이 전형적인 배치
3. 스트림 처리 모델
도착하는 대로 (또는 짧은 윈도우로) 처리한다. job은 끝나지 않고 돈다.

| 단계 | 역할 |
|---|---|
| Ingest | Kafka 등 버퍼·순서·내구 |
| Process | filter · aggregate · join (state) |
| Sink | DB, cache, alert, downstream topic |
events/s ──► consumer ──► 1-min tumbling count ──► alert if error_rate > 1%
- 장점 — 낮은 latency, 이상·사기·운영 알림에 적합
- 한계 — 상태·순서·중복 처리 비용, 정확히 한 번은 어려움
- Micro-batch (Spark Structured Streaming) — 초~분 윈도우로 배치 엔진 재사용 — “스트림 API, 배치 실행”
- Continuous에 가까울수록 — infra·디버깅·일관성 비용 상승
4. Latency vs Throughput
같은 데이터라도 얼마나 빨리 vs 얼마나 많이가 동시에 최대가 아니다.

| 모델 | 전형 latency | Throughput | 비용 패턴 |
|---|---|---|---|
| Batch (daily) | T+1 ~ T+0 h | 매우 높음 (대량 scan) | 피크에 클러스터 키움 |
| Micro-batch | 초~분 | 중~높음 | 상시 작은 cluster |
| Stream | ms~초 | 이벤트당 비용 | 상시 운영·모니터링 |
- Throughput — 단위 시간 처리량 (rows/s, GB/h). 배치가 대량 scan에 유리
- Latency — 이벤트 발생 → 결과까지. 알림·대시보드는 tail latency가 SLA
- Velocity(3V)가 크면 ingest는 필수 — 처리는 스트림·micro-batch, 집계 리포트는 배치로 보완하는 경우 많음
- 잘못된 선택 — 일 리포트만 필요한데 24/7 Flink — 운영만 늘고 이득 없음
# code/batch-stream-signals.yaml (발췌)
workloads:
- name: daily-revenue-report
need: "correctness · full day slice"
model: batch
sla: "ready by 06:00"
- name: payment-fraud-score
need: "score within 2s of auth"
model: stream
sla: "p99 < 2s"
- name: feature-table-user-day
need: "T+1 table + same-day partial"
model: "batch daily + micro-batch refresh"
5. Use case 선택
요구사항을 질문으로 바꾸면 선택이 선명해진다.

| 질문 | 쪽 | 예 |
|---|---|---|
| 언제까지 맞으면 되나? | 내일 아침 → batch | 매출 일보, 월간 정산 |
| 몇 초 안에? | stream / micro-batch | 사기, SLO 위반 알림 |
| 전체 재계산이 자주? | batch + immutable raw | backfill, 스키마 변경 |
| 같은 키 순서가 중요? | partition 스트림 | 주문 상태 머신 |
| 학습용 정답 라벨이 늦게? | batch label join | 클릭→구매 전환 (며칠 lag) |
흔한 조합 (하이브리드)
| 패턴 | 배치 | 스트림 |
|---|---|---|
| Lambda (개요) | 정확한 일일 집계 | 실시간 근사·알림 |
| Kappa (개요) | 재처리만 배치처럼 replay | 일상은 한 스트림 파이프라인 |
| 실무 단순화 | warehouse 일 snapshot | Kafka → 운영 metric·CDC fan-out |
- Lambda — 두 코드 경로 유지 비용 — 가능하면 한 엔진(Spark batch + streaming)으로 통합 추세
- Kappa — topic retention·replay로 backfill — ordering·버전 관리 필요
- ELK는 로그 검색에 가깝고 — 본 시리즈는 테이블·피처로 가는 분석 경로
6. 설계 체크리스트
| # | 질문 |
|---|---|
| 1 | 입력이 bounded slice로 정의 가능한가 |
| 2 | SLA가 초 단위인가 시·일 단위인가 |
| 3 | 재처리·backfill 빈도와 비용은 |
| 4 | 정확히 한 번이 필요한가 at-least-once로 충분한가 |
| 5 | 스트림만 쓸 때 일일 정합 리포트 대안이 있는가 |
| 6 | micro-batch interval이 SLA를 실제로 만족하는가 |
정리
- Bounded → 배치·스냅샷·backfill, Unbounded → buffer·상시 job·윈도우
- 배치 — throughput·정합·재실행, 스트림 — latency·운영 반응
- Velocity만으로 스트림을 고르지 말고 — 질문·SLA·재처리로 결정
- 하이브리드가 흔함 — raw는 스트림, 골드 테이블은 일 배치
다음에 다룰 것
- Kafka 기초
- topic·partition·consumer group, retention, ordering
해당 내용은 Kleppmann — Designing Data-Intensive Applications, Spark Structured Streaming documentation 을 기반으로 합니다.
'Data & AI' 카테고리의 다른 글
| Spark Structured Streaming (0) | 2026.07.13 |
|---|---|
| Spark 배치 처리 (0) | 2026.07.09 |
| Kafka 기초 (0) | 2026.07.05 |
| 데이터 규모와 아키텍처 (0) | 2026.07.02 |
| Data · AI 오리엔테이션 (0) | 2026.07.01 |