Skip to content

iq-dev-lab/stream-processing-deep-dive

Repository files navigation

🌊 Stream Processing Deep Dive

"스트림을 처리하는 것과, 이벤트 시간·Watermark·상태·체크포인트가 정확성을 어떻게 보장하는지 아는 것은 다르다"


"끝나지 않는 데이터 흐름에서 왜 늦은 이벤트도 정확히 집계되고, 장애 후에도 정확히 한 번 처리되는가"

이벤트 시간 vs 처리 시간, Watermark의 완전성-지연 트레이드오프, 키 상태와 RocksDB 백엔드, Chandy-Lamport 분산 스냅샷과 end-to-end Exactly-Once까지 왜 이렇게 동작하는가 라는 질문으로 Flink의 내부를 끝까지 파헤칩니다


GitHub Flink Kafka Docker Docs License


🎯 이 레포에 대하여

스트림 처리 자료는 넘쳐납니다. 하지만 대부분은 "어떻게 쓰나" 에서 멈춥니다.

일반 자료 이 레포
"스트림은 끝없는 데이터다" 무한 데이터에서 "이벤트 시간"과 "처리 시간"이 갈라지는 순간, 늦은 이벤트가 집계를 어떻게 깨뜨리는지 직접 재현
"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 종합)는 지금까지의 모든 개념을 한 파이프라인으로 모으는 클라이맥스입니다.

Concepts Time Windowing State Checkpoint Join Ops


📚 전체 학습 지도

💡 각 섹션을 클릭하면 상세 문서 목록이 펼쳐집니다


🔹 Chapter 1: 스트림 처리의 개념

핵심 질문: 끝나지 않는 데이터를 어떻게 처리한다는 말인가? 배치와는 무엇이 본질적으로 다른가?

배치 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, 파이프라인의 실행 그래프

🔹 Chapter 2: 시간과 Watermark

핵심 질문: "언제 일어났나"와 "언제 처리하나"가 다를 때, 정확한 집계는 어떻게 가능한가?

세 가지 시간, 이벤트 시간 처리, 늦은 이벤트, Watermark의 생성과 동작까지 (6개 문서)
문서 다루는 내용
01. 세 가지 시간 이벤트 시간 / 수집 시간 / 처리 시간의 정의와 차이, 왜 구분해야 하는가 — 정확성이 어디서 무너지는지
02. 이벤트 시간 처리 "언제 일어났나"를 기준으로 집계하는 모델, 타임스탬프 추출과 이벤트 시간 영역에서의 진행 개념
03. 늦은 이벤트 네트워크 지연·재시도로 순서가 뒤바뀐 이벤트, 무한정 기다릴 수 없음 — 완전성과 진행의 근본 충돌
04. Watermark "이 시간 이전 이벤트는 모두 도착했다"는 진행 신호의 정체, Watermark가 윈도우 마감과 결과 방출을 트리거하는 방식
05. Watermark 생성 전략 단조 증가 vs bounded out-of-orderness, 휴리스틱 기반 생성, 얼마나 기다릴 것인가의 설계 결정
06. 늦은 데이터 처리 allowed lateness로 윈도우 재트리거, side output으로 격리, 완전성 vs 지연의 명시적 제어

🔹 Chapter 3: 윈도잉

핵심 질문: 무한 스트림을 어떻게 유한한 집계 단위로 쪼개는가? 결과는 언제 방출되는가?

윈도우 개념, 텀블링·슬라이딩·세션, 트리거, 늦은 데이터 결합까지 (6개 문서)
문서 다루는 내용
01. 윈도우 개념 무한 스트림을 "유한 청크"로 자르는 추상화, 윈도우 할당자(Assigner)와 윈도우 = 함수의 시각
02. 텀블링 윈도우 고정·비겹침 윈도우(예: 매분), 가장 단순한 집계 단위, 경계 처리와 시작점 정렬의 미묘함
03. 슬라이딩 윈도우 겹치는 윈도우로 이동 평균 계산, 한 이벤트가 여러 윈도우에 속하는 비용, 메모리 영향
04. 세션 윈도우 활동 간격(inactivity gap) 기반 동적 경계, 세션 병합이 일어나는 메커니즘, 사용자 행동 분석의 표준
05. 윈도우 트리거 "언제 결과를 내보낼 것인가"의 분리된 추상화 — Watermark 기반 / 카운트 기반 / 커스텀, 이른 트리거로 부분 결과
06. 윈도우 + 늦은 데이터 윈도우가 마감된 후 도착한 이벤트의 처리, allowed lateness × 윈도우 결합, 재트리거의 방출 의미론

🔹 Chapter 4: 상태 관리

핵심 질문: 스트림 연산이 과거를 기억하는 방식 — 어떻게 보관하고, 어떻게 재분배되며, 어떻게 폭발을 막는가?

상태가 필요한 이유, 상태 종류, 백엔드, 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. 상태 스키마 진화 저장된 상태의 스키마가 바뀔 때 호환성 확보, 마이그레이션 전략과 역호환성을 잃는 변경

🔹 Chapter 5: 체크포인트와 Exactly-Once

핵심 질문: 장애 후 "정확히 한 번"이 어떻게 보장되는가 — 소스부터 싱크까지 무엇이 필요한가?

체크포인트, 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 죽음 → 마지막 체크포인트에서 상태·오프셋 복원, 재처리되는 구간과 외부 효과의 책임

🔹 Chapter 6: 조인과 고급 패턴

핵심 질문: 두 스트림을 어떻게 결합하고, 백프레셔로 흐름을 조율하며, 정확성·지연·처리량을 어떻게 절충하는가?

스트림 조인, 스트림-테이블 조인, 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차원 트레이드오프

🔹 Chapter 7: 운영과 측정

핵심 질문: 실제 운영에서 무엇을 모니터링하고, 어떻게 스케일하며, 어떤 함정을 피해야 하는가?

모니터링, 스케일·재조정, 흔한 함정, 종합 구현까지 (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 · 상태 머신 응용
                                          데이터 레이어의 완성

🙏 Reference


⭐️ 도움이 되셨다면 Star를 눌러주세요!

Made with ❤️ by Dev Book Lab


"스트림을 처리하는 것과, 이벤트 시간·Watermark·상태·체크포인트가 정확성을 어떻게 보장하는지 아는 것은 다르다"

About

스트림을 처리하는 것과, 이벤트 시간·Watermark·상태·체크포인트가 정확성을 어떻게 보장하는지 아는 것은 다르다

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors