"스트림을 처리하는 것과, 이벤트 시간·Watermark·상태·체크포인트가 정확성을 어떻게 보장하는지 아는 것은 다르다"
"끝나지 않는 데이터 흐름에서 왜 늦은 이벤트도 정확히 집계되고, 장애 후에도 정확히 한 번 처리되는가"
이벤트 시간 vs 처리 시간, Watermark의 완전성-지연 트레이드오프, 키 상태와 RocksDB 백엔드, Chandy-Lamport 분산 스냅샷과 end-to-end Exactly-Once까지 왜 이렇게 동작하는가 라는 질문으로 Flink의 내부를 끝까지 파헤칩니다
스트림 처리 자료는 넘쳐납니다. 하지만 대부분은 "어떻게 쓰나" 에서 멈춥니다.
| 일반 자료 | 이 레포 |
|---|---|
| "스트림은 끝없는 데이터다" | 무한 데이터에서 "이벤트 시간"과 "처리 시간"이 갈라지는 순간, 늦은 이벤트가 집계를 어떻게 깨뜨리는지 직접 재현 |
| "Watermark는 진행 신호다" | Watermark가 휴리스틱으로 생성되는 방식, bounded out-of-orderness가 만드는 완전성 vs 지연 트레이드오프를 Flink UI로 관찰 |
| "윈도우는 집계 단위다" | 텀블링·슬라이딩·세션 윈도우가 트리거와 결합되어 결과를 언제 방출하는지, 윈도우 마감 후 도착한 이벤트 처리 |
| "Flink는 상태를 보관한다" | keyed state vs operator state, 힙 vs RocksDB 백엔드, 큰 상태에서의 디스크 IO와 키 재분배 비용 |
| "체크포인트로 복구된다" | Chandy-Lamport barrier가 스트림에 삽입되어 일관된 글로벌 스냅샷이 만들어지는 과정을 barrier 정렬로 추적 |
| "Exactly-Once를 지원한다" | 소스 오프셋 + 상태 스냅샷 + 트랜잭션 싱크가 결합되어야 end-to-end가 성립함을 TaskManager를 죽여 검증 |
| 이론 나열 | docker-compose(Flink+Kafka) + 늦은 이벤트 주입 + 장애 주입 + Flink UI Watermark·체크포인트 관찰 |
선행 학습 권장: Kafka Deep Dive — 스트림 소스와 오프셋의 토대. Distributed Systems Theory Deep Dive — 상태·일관성·Exactly-Once의 이론적 기반.
# 검증 환경 1줄 기동
git clone https://github.com/dev-book-lab/stream-processing-deep-dive
cd stream-processing-deep-dive && docker-compose up -d
# → Flink UI: http://localhost:8081, Kafka: localhost:9092각 챕터의 첫 문서부터 바로 학습을 시작하세요. 마지막 문서(Ch7-04 종합)는 지금까지의 모든 개념을 한 파이프라인으로 모으는 클라이맥스입니다.
💡 각 섹션을 클릭하면 상세 문서 목록이 펼쳐집니다
핵심 질문: 끝나지 않는 데이터를 어떻게 처리한다는 말인가? 배치와는 무엇이 본질적으로 다른가?
배치 vs 스트림, 처리 모델, 어려움의 원천, 처리 보장, 아키텍처까지 (5개 문서)
| 문서 | 다루는 내용 |
|---|---|
| 01. 배치 vs 스트림 | 유한 vs 무한 데이터의 본질적 차이, "데이터가 끝나지 않는다"는 가정이 집계·정렬·정확성 모두를 어떻게 바꾸는가 |
| 02. 스트림 처리 모델 | 레코드별 처리(Flink) vs 마이크로배치(Spark Streaming), 지연 vs 처리량의 모델 수준 트레이드오프 |
| 03. 왜 어려운가 | 순서가 뒤바뀐 입력, 늦은 이벤트, 장애 복구, 상태 보존 — 무한 흐름이 만드는 네 가지 문제 |
| 04. 처리 보장 | at-most-once / at-least-once / exactly-once, 각 보장의 비용과 구현 메커니즘(distributed 이론 연결) |
| 05. 아키텍처 | Source → 연산 → Sink의 분산 실행, JobManager / TaskManager / Slot, 파이프라인의 실행 그래프 |
핵심 질문: "언제 일어났나"와 "언제 처리하나"가 다를 때, 정확한 집계는 어떻게 가능한가?
세 가지 시간, 이벤트 시간 처리, 늦은 이벤트, Watermark의 생성과 동작까지 (6개 문서)
| 문서 | 다루는 내용 |
|---|---|
| 01. 세 가지 시간 | 이벤트 시간 / 수집 시간 / 처리 시간의 정의와 차이, 왜 구분해야 하는가 — 정확성이 어디서 무너지는지 |
| 02. 이벤트 시간 처리 | "언제 일어났나"를 기준으로 집계하는 모델, 타임스탬프 추출과 이벤트 시간 영역에서의 진행 개념 |
| 03. 늦은 이벤트 | 네트워크 지연·재시도로 순서가 뒤바뀐 이벤트, 무한정 기다릴 수 없음 — 완전성과 진행의 근본 충돌 |
| 04. Watermark | "이 시간 이전 이벤트는 모두 도착했다"는 진행 신호의 정체, Watermark가 윈도우 마감과 결과 방출을 트리거하는 방식 |
| 05. Watermark 생성 전략 | 단조 증가 vs bounded out-of-orderness, 휴리스틱 기반 생성, 얼마나 기다릴 것인가의 설계 결정 |
| 06. 늦은 데이터 처리 | allowed lateness로 윈도우 재트리거, side output으로 격리, 완전성 vs 지연의 명시적 제어 |
핵심 질문: 무한 스트림을 어떻게 유한한 집계 단위로 쪼개는가? 결과는 언제 방출되는가?
윈도우 개념, 텀블링·슬라이딩·세션, 트리거, 늦은 데이터 결합까지 (6개 문서)
| 문서 | 다루는 내용 |
|---|---|
| 01. 윈도우 개념 | 무한 스트림을 "유한 청크"로 자르는 추상화, 윈도우 할당자(Assigner)와 윈도우 = 함수의 시각 |
| 02. 텀블링 윈도우 | 고정·비겹침 윈도우(예: 매분), 가장 단순한 집계 단위, 경계 처리와 시작점 정렬의 미묘함 |
| 03. 슬라이딩 윈도우 | 겹치는 윈도우로 이동 평균 계산, 한 이벤트가 여러 윈도우에 속하는 비용, 메모리 영향 |
| 04. 세션 윈도우 | 활동 간격(inactivity gap) 기반 동적 경계, 세션 병합이 일어나는 메커니즘, 사용자 행동 분석의 표준 |
| 05. 윈도우 트리거 | "언제 결과를 내보낼 것인가"의 분리된 추상화 — Watermark 기반 / 카운트 기반 / 커스텀, 이른 트리거로 부분 결과 |
| 06. 윈도우 + 늦은 데이터 | 윈도우가 마감된 후 도착한 이벤트의 처리, allowed lateness × 윈도우 결합, 재트리거의 방출 의미론 |
핵심 질문: 스트림 연산이 과거를 기억하는 방식 — 어떻게 보관하고, 어떻게 재분배되며, 어떻게 폭발을 막는가?
상태가 필요한 이유, 상태 종류, 백엔드, TTL, 키 파티셔닝, 스키마 진화까지 (6개 문서)
| 문서 | 다루는 내용 |
|---|---|
| 01. 상태가 필요한 이유 | 집계·조인·중복 제거가 과거를 기억해야 가능한 이유, 스트림 연산의 stateless / stateful 구분 |
| 02. 상태 종류 | Keyed state vs Operator state, ValueState / ListState / MapState / ReducingState의 사용 시나리오 |
| 03. 상태 백엔드 | HashMapStateBackend(힙) vs EmbeddedRocksDB, 큰 상태가 메모리를 넘어설 때 디스크로 내려가는 메커니즘과 IO 비용 |
| 04. 상태 크기 관리 | TTL 설정과 정리 전략, 상태 무한 증가 시나리오와 회피법, 컴팩션이 처리량에 미치는 영향 |
| 05. 상태와 키 파티셔닝 | 키별 상태가 어느 TaskManager에 위치하는지, 병렬성 변경 시 키 그룹 단위로 재분배되는 과정(distributed 연결) |
| 06. 상태 스키마 진화 | 저장된 상태의 스키마가 바뀔 때 호환성 확보, 마이그레이션 전략과 역호환성을 잃는 변경 |
핵심 질문: 장애 후 "정확히 한 번"이 어떻게 보장되는가 — 소스부터 싱크까지 무엇이 필요한가?
체크포인트, Chandy-Lamport, barrier 정렬, end-to-end Exactly-Once, 장애 복구까지 (6개 문서)
| 문서 | 다루는 내용 |
|---|---|
| 01. 체크포인트 | 상태 스냅샷을 주기적으로 저장하는 메커니즘, 체크포인트 간격·크기·정렬 시간이 만드는 트레이드오프 |
| 02. Chandy-Lamport 알고리즘 | 분산 스냅샷의 고전 알고리즘이 Flink에 어떻게 적용되었는지, 글로벌 일관 상태의 정의 |
| 03. barrier 정렬 | 스트림에 barrier 마커를 삽입해 일관된 스냅샷을 만드는 과정, aligned vs unaligned 체크포인트의 차이 |
| 04. Exactly-Once 의미론 | 체크포인트 + 멱등성 / 트랜잭션 싱크 = Exactly-Once, 효과 측면의 한 번이라는 정확한 의미 |
| 05. 소스·싱크 보장 | Kafka 오프셋 커밋과 Flink 체크포인트의 결합, 2-phase commit 싱크 커넥터의 end-to-end 보장 |
| 06. 장애 복구 | TaskManager 죽음 → 마지막 체크포인트에서 상태·오프셋 복원, 재처리되는 구간과 외부 효과의 책임 |
핵심 질문: 두 스트림을 어떻게 결합하고, 백프레셔로 흐름을 조율하며, 정확성·지연·처리량을 어떻게 절충하는가?
스트림 조인, 스트림-테이블 조인, CEP, 백프레셔, 트레이드오프까지 (5개 문서)
| 문서 | 다루는 내용 |
|---|---|
| 01. 스트림 조인 | 윈도우 조인과 interval join, 두 무한 스트림을 어디까지 기억해서 결합할지의 상태 비용 |
| 02. 스트림-테이블 조인 | 참조 데이터로 enrichment, broadcast state로 작은 테이블을 모든 TaskManager에 복제, 변화하는 차원의 처리 |
| 03. CEP — 복합 이벤트 처리 | 패턴 매칭의 정의(A then B within 5s), NFA 상태 그래프로 컴파일되는 원리, 지연된 이벤트가 패턴에 미치는 영향 |
| 04. 백프레셔 | 느린 다운스트림이 업스트림을 자연스럽게 감속시키는 메커니즘, Flink의 credit-based 흐름 제어 |
| 05. 정확성 vs 지연 vs 처리량 | 스트림 처리의 세 가지 핵심 축, 각 설정(Watermark 지연·체크포인트 주기·병렬성)이 만드는 3차원 트레이드오프 |
핵심 질문: 실제 운영에서 무엇을 모니터링하고, 어떻게 스케일하며, 어떤 함정을 피해야 하는가?
모니터링, 스케일·재조정, 흔한 함정, 종합 구현까지 (4개 문서)
| 문서 | 다루는 내용 |
|---|---|
| 01. 모니터링 | 처리량 / 지연(latency) / 체크포인트 시간 / 백프레셔 지표를 Flink UI와 메트릭으로 어디서 보는지 |
| 02. 스케일·재조정 | 병렬성 변경 시 상태가 키 그룹 단위로 재분배되는 과정, savepoint 기반 무중단 재조정 |
| 03. 흔한 함정 | Watermark 잘못 설정으로 결과 누락 / 상태 폭발 / 체크포인트 실패 / 백프레셔 누적 — 진단 패턴과 회피법 |
| 04. 종합 — 이벤트 시간 파이프라인 | Kafka 소스 → 이벤트 시간 윈도우 집계 → Exactly-Once 싱크를 직접 구현하고 TaskManager를 죽여 복구 검증 |
🟢 "Watermark와 Exactly-Once를 정확히 알고 싶다" — 면접/실무 의문 해소 (2주)
Week 1 — 시간과 정확성
Ch1-04 처리 보장
Ch2-01 세 가지 시간
Ch2-03 늦은 이벤트
Ch2-04 Watermark
Week 2 — 체크포인트와 보장
Ch5-01 체크포인트
Ch5-02 Chandy-Lamport
Ch5-04 Exactly-Once 의미론
Ch5-05 소스·싱크 보장
🔵 스트림 처리 내부를 원리로 이해하고 싶은 개발자 (7주)
Week 1 Chapter 1 전체 — 스트림 처리의 개념
Week 2 Chapter 2 전체 — 시간과 Watermark
Week 3 Chapter 3 전체 — 윈도잉
Week 4 Chapter 4 전체 — 상태 관리
Week 5 Chapter 5 전체 — 체크포인트와 Exactly-Once
Week 6 Chapter 6 전체 — 조인과 고급 패턴
Week 7 Chapter 7 전체 — 운영·측정·종합 구현
🔴 운영 중인 파이프라인의 정확성 문제를 해결해야 하는 개발자 (집중 코스)
핵심 경로 (Flink UI에서 직접 관찰하며 진행)
Step 1 Ch2-01,03,04 시간 모델과 Watermark
Step 2 Ch2-05~06 Watermark 전략과 늦은 데이터
Step 3 Ch3-05~06 트리거와 윈도우+늦은 데이터
Step 4 Ch4-03~04 상태 백엔드와 크기 관리
Step 5 Ch5-01,03 체크포인트와 barrier 정렬
Step 6 Ch6-04 백프레셔
Step 7 Ch7-01,03 모니터링과 흔한 함정
각 문서의 "📊 측정" 섹션에서 Flink UI 스크린샷과 메트릭을 확인하세요.
모든 문서는 동일한 구조로 작성됩니다.
| 섹션 | 설명 |
|---|---|
| 🎯 핵심 질문 | 이 문서를 읽고 나면 답할 수 있는 질문 |
| 🔍 왜 이게 존재하는가 | 무한 스트림이 만드는 문제 상황과 설계 배경 |
| 😱 흔한 오해 또는 잘못된 사용 | Before — 많은 개발자가 틀리는 방식 |
| ✨ 올바른 이해와 사용 | After — 원리를 알고 난 후의 올바른 접근 |
| 🔬 내부 동작 원리 | Watermark 전파 / barrier 정렬 / 상태 백엔드의 디스크 구조 + Flink 소스 추적 |
| 💻 실전 실험 | 실행 가능한 Flink Job + Kafka 입력 주입 + Flink UI 관찰 + 장애 주입 |
| 📊 측정 | 윈도우 / 보장 수준 / 백엔드별 정확성·지연·처리량의 정량 비교 |
| 🤔 트레이드오프 | 이 설계의 장단점, 언제 다른 방법을 택할 것인가 |
| 📌 핵심 정리 | 한 화면 요약 |
| 🤔 생각해볼 문제 | 개념을 더 깊이 이해하기 위한 질문 + 해설 |
docker-compose로 Flink + Kafka를 띄우고 이벤트 주입 + 장애 주입 + Flink UI 관찰 로 검증합니다.
# docker-compose.yml — Flink + Kafka
services:
jobmanager:
image: flink:1.18
command: jobmanager
ports: ["8081:8081"] # Flink UI
taskmanager:
image: flink:1.18
command: taskmanager
depends_on: [jobmanager]
kafka:
image: bitnami/kafka:3.6
ports: ["9092:9092"]
prometheus:
image: prom/prometheus:latest
ports: ["9090:9090"] # Flink 메트릭 수집
grafana:
image: grafana/grafana:latest
ports: ["3000:3000"] # Watermark·체크포인트·백프레셔 대시보드# 핵심 검증 절차
# 1) 이벤트 시간 집계
# 타임스탬프가 박힌 이벤트를 Kafka에 주입 → 윈도우 집계 결과 확인
# 2) 늦은 이벤트 실험
# 순서가 뒤섞인 이벤트를 의도적으로 주입
# → Watermark / allowed lateness 효과를 Flink UI에서 관찰
# 3) Watermark 진행 관찰
# Flink UI → Job → Watermarks 탭
# operator별 현재 Watermark, 진행 멈춤 진단
# 4) 체크포인트 검증
# Flink UI → Checkpoints 탭
# 주기 / 정렬 시간 / 크기 / 실패율
# 5) Exactly-Once 검증 (핵심 실험)
# 처리 중 docker kill <taskmanager>
# → 재시작 후 결과의 중복 / 누락이 0인지 확인
# 6) 상태 백엔드 비교
# HashMapStateBackend vs EmbeddedRocksDB
# 상태 크기를 100MB / 1GB / 10GB로 늘려가며 체크포인트 시간과 처리량 변화
# 7) 백프레셔 진단
# Sink에 의도적 지연 주입 → Flink UI의 백프레셔 지표가 업스트림으로 전파되는 모습
# 8) Prometheus 메트릭 + Grafana 대시보드
# flink_taskmanager_job_task_operator_currentEmitWatermark,
# flink_jobmanager_job_lastCheckpointDuration,
# flink_taskmanager_job_task_backPressuredTimeMsPerSecond 추적⬆️ 선행 학습
kafka-deep-dive → 스트림 소스, 오프셋, 파티션
distributed-systems-theory-deep-dive → 상태·일관성·Exactly-Once의 이론
🤝 시너지
spark-internals-deep-dive → 배치 vs 스트림의 대조, 마이크로배치 모델
columnar-storage-format-deep-dive → 스트림 결과의 싱크 (Iceberg, Parquet)
realtime-client-networking-deep-dive → 클라이언트 스트림(WebSocket·SSE) 대조
🧬 수렴
data-platform-architecture → 분산 이론의 Exactly-Once · 상태 머신 응용
데이터 레이어의 완성
- Streaming Systems — Tyler Akidau, Slava Chernyak, Reuven Lax (O'Reilly) — 핵심 교재
- Apache Flink 공식 문서
- "The Dataflow Model" 논문 — Google
- "Streaming 101 / 102" — Tyler Akidau, O'Reilly
- Kafka Streams 문서 — 대안 모델 비교
- "Lightweight Asynchronous Snapshots for Distributed Dataflows" 논문 — Flink 체크포인트 알고리즘
- Flink 소스 — apache/flink
⭐️ 도움이 되셨다면 Star를 눌러주세요!
Made with ❤️ by Dev Book Lab
"스트림을 처리하는 것과, 이벤트 시간·Watermark·상태·체크포인트가 정확성을 어떻게 보장하는지 아는 것은 다르다"