백엔드 데이터 인프라 121편 — Kafka Streams 입문 (라이브러리 모델·왜)

2026-05-17백엔드 데이터 인프라

백엔드 데이터 인프라 121편. Kafka Streams 입문 — 별도 cluster 가 아닌 라이브러리 모델·Java/Scala 애플리케이션·exactly-once·Kafka 내장 통합·Spark Streaming·Flink 와의 결정적 차이까지 풀어쓴 학습 노트. Part 5-10 Streams 시작.

📚 백엔드 데이터 인프라 · 121편 — Kafka Streams 입문 (라이브러리 모델·왜)

이 글은 백엔드 데이터 인프라 시리즈 130편 중 121편이에요. Part 5-9 Connect 까지 끝났다면, 이번 121편부터는 Part 5-10 — Kafka Streams (9편). 첫 글은 Kafka Streams 의 정체성·왜·Spark/Flink 와 어떻게 다른가.

Kafka Streams가 어렵게 느껴지는 이유

Stream processing(실시간 데이터 흐름 처리) 영역은 도구가 여러 개라 헷갈려요. Spark, Flink(저지연 스트림 엔진), Kafka Streams, Samza(분산 스트림 처리 프레임워크) 가 각자 다른 모델로 같은 문제를 풀고 있거든요. 그래서 왜 굳이 Kafka Streams 인지가 한 번에 안 잡혀요.

첫째, 라이브러리 vs 클러스터 모델 차이가 있어요. Spark·Flink 는 별도 cluster 를 두고 거기에 job 을 던지는 구조고, Kafka Streams 는 내 애플리케이션 안에 라이브러리로 들어가요.

둘째, KStream vs KTable 개념. Stream-table duality(스트림과 테이블이 같은 데이터의 두 관점) 가 처음 보면 추상적이에요.

셋째, 언제 Kafka Streams 를 쓰고 언제 Spark·Flink 를 쓸지 기준이 안 잡혀요.

이 글에서 정체성·핵심 개념·도구 비교까지.

Kafka Streams 의 정체성

"Kafka Streams is a client library for building applications and microservices, where the input and output data are stored in Kafka clusters."

핵심: 별도 cluster 없는 client 라이브러리예요.

  • Java/Scala 애플리케이션 코드 안에 포함
  • 자체 microservice 로 배포
  • Kafka cluster 만 별도 인프라
[Kafka Cluster]
    ↑↓
[My Microservice (Spring Boot + kafka-streams)]
   - Stream Processing 로직
   - 자체 운영

Spark·Flink 처럼 별도 cluster 를 운영할 부담이 없어요.

핵심 장점

  • Elastic·Scalable·Fault-tolerant — Kafka 의 partition 기반 자동 분산
  • Containers·VMs·Bare metal·Cloud — 일반 Java 애플리케이션 처럼 배포
  • Exactly-once Semantics (EOS) — 정확히 한 번 처리 보장. 88·112편 EOS 모델
  • No separate cluster — Kafka 만 있으면 됨
  • Kafka 통합 — security·monitoring 모두 자연스러움
  • Mac/Linux/Windows — 개발 환경 자유

사용 사례 — Real-world

  • New York Times — 출판된 content 를 실시간 distribution
  • Pinterest — 광고 예산 실시간 처리
  • Rabobank — Fraud detection(이상 거래 탐지)
  • Trivago — 호텔 검색 데이터 enrichment(보강)
  • Zalando — 추천 시스템

대부분 실시간 ETL(추출·변환·적재)·이벤트 보강·집계·탐지 영역이에요.

라이브러리 모델 vs 클러스터 모델

Spark Streaming·Flink (Cluster 모델)

[Spark/Flink Cluster] ── 별도 인프라 ──
       │
       │ submit job
       ↓
[Stream Processing Jobs]
       │
       │ source/sink
       ↓
[Kafka], [DB], [HDFS], [S3]

장점:

  • 매우 강력 (batch + streaming, ML, SQL)
  • 풍부한 생태계 (Kafka 외 다양한 source/sink)
  • 대규모 (수천 노드)

단점:

  • 별도 cluster 운영 부담 — 인프라 + 모니터링 + upgrade
  • Job 제출·관리 (YARN(하둡 자원 관리자)·Kubernetes 등)
  • Deploy 복잡

Kafka Streams (라이브러리 모델)

[My Spring Boot Microservice]
   - kafka-streams.jar
   - Stream 로직
   - 자체 deploy
       │
       │ source/sink
       ↓
[Kafka Only]

장점:

  • 단순 — Java 애플리케이션처럼 배포
  • 운영 부담 ↓ (Kafka 만)
  • 마이크로서비스 친화

단점:

  • Kafka 외 source/sink X (Connect 와 결합 필요)
  • 매우 큰 분산 처리 어려움 (Spark·Flink 보다)

선택 가이드

시나리오 권장
Kafka 안 데이터 + 마이크로서비스 Kafka Streams
대규모 분산 ETL + ML Spark
매우 낮은 latency + 복잡한 stream Flink
Batch + Streaming 통합 Spark / Flink
Connect + 가벼운 변환 Kafka Streams (또는 SMT, 118편)

대부분의 Kafka 중심 microservice 는 Kafka Streams 가 답이에요.

KStream vs KTable — 핵심 개념

KStream — record stream (이벤트 흐름)
KTable  — changelog stream (현재 상태)

KStream

("user42", "login") at t=1
("user42", "purchase") at t=2
("user42", "logout") at t=3

모든 이벤트가 append-only(이어 붙이기만 함). 각 이벤트가 독립이에요.

KStream<String, String> events = builder.stream("user-events");

KTable

("user42", "online") at t=1     → 현재: online
("user42", "offline") at t=2    → 현재: offline
("user42", "online") at t=3     → 현재: online

각 key 의 최신 값만 의미. Compacted topic(키별 최신 값만 남기는 토픽) 과 자연스럽게 매칭.

KTable<String, String> userStatus = builder.table("user-status");

Duality

KStream → groupByKey().reduce() → KTable    (집계로 상태 추출)
KTable → toStream() → KStream                 (상태를 다시 stream 으로)

같은 데이터를 두 가지 관점으로 보는 거예요. 이게 Stream-Table Duality.

가장 단순한 예제

StreamsBuilder builder = new StreamsBuilder();

KStream<String, String> input = builder.stream("input-topic");

input
    .filter((key, value) -> value.startsWith("important"))
    .mapValues(value -> value.toUpperCase())
    .to("output-topic");

KafkaStreams streams = new KafkaStreams(builder.build(), props);
streams.start();

// graceful shutdown
Runtime.getRuntime().addShutdownHook(new Thread(streams::close));

5줄로 input topic → filter → uppercase → output topic 까지 끝나요. Stream 처리 시작.

DSL vs Processor API

Kafka Streams 는 추상화 단계가 두 개예요.

DSL (High-level)

input
    .filter(...)
    .mapValues(...)
    .groupByKey()
    .windowedBy(...)
    .reduce(...)
    .to(...);

DSL(도메인 특화 언어) 은 선언적이고 간단해서 90% 환경에 충분해요. 125편 깊이.

Processor API (Low-level)

Topology topology = new Topology();
topology.addSource("source", "input-topic");
topology.addProcessor("processor", MyProcessor::new, "source");
topology.addSink("sink", "output-topic", "processor");

세밀 제어·custom logic 가 필요할 때 써요. 126편 깊이.

핵심 Topology 개념

Topology = Source → Processor 들 → Sink

Topology(스트림 처리 흐름의 그래프 구조) 가 곧 processing graph 예요. Kafka Streams 가 이 graph 를 task 들로 쪼개 Kafka partition 에 매핑해요.

핵심 Use Cases (다음 편들에서 깊이)

  • 단순 변환 — filter·map·flatMap (125편 DSL)
  • 집계 — count·sum·aggregate (127편 stateful)
  • Window 처리 — tumbling·hopping·session window (127편)
  • Join — KStream-KStream·KStream-KTable·KTable-KTable (125편)
  • Stateful processing — RocksDB(임베디드 키-값 저장소) local state store (127편)
  • Interactive Queries — state 외부 query (127편)

학습 로드맵

Part 5-10 Streams 9편:

  • 121 Intro (이 글) — 정체성·라이브러리 모델·KStream/KTable
  • 122 Quickstart — 직접 만져보기
  • 123 Core Concepts — Topology·Task·Thread·Partition 매핑
  • 124 Write & Run App — Spring Boot 통합·운영
  • 125 DSL — filter·map·groupBy·join·...
  • 126 Processor API — low-level
  • 127 Stateful + Interactive Queries — state store·windowing·외부 query
  • 128 Testing — TopologyTestDriver·integration
  • 129 운영 — security·manage topics·app reset tool

이 시리즈가 끝나면 Kafka Streams 의 거의 모든 영역을 다룬 셈이에요.

한계·실무 함정

1. Kafka 외 source/sink

Kafka Streams 는 Kafka in·Kafka out 이 전제예요. DB·HTTP API 가 source 라면 Connect 와 결합해야 해요.

2. 대규모 분산

수천 노드 ETL 은 Spark·Flink 영역이고, Kafka Streams 는 수십~수백 instance 정도가 적정선이에요.

3. State 의 disk·메모리 비용

stateful 처리는 RocksDB local + changelog topic 으로 돌아가요. state 가 커지면 그만큼 부담이 늘어요.

4. 학습 곡선

DSL 자체는 단순한데 stateful·windowing·join 으로 들어가면 깊이가 확 커져요.

5. 운영 — 일반 Java 앱이지만 stream 처리 특수성

reprocess·offset reset·state restore 같은 별도 운영 도구가 필요해요 (129편).

시험 직전 한 번 더 — Kafka Streams 입문 함정 압축 노트

  • Kafka Streams = client 라이브러리 (별도 cluster X)
  • Java/Scala 애플리케이션 안에 포함
  • 장점 — Elastic·EOS·No separate cluster·Kafka 통합·microservice 친화
  • 단점 — Kafka 외 source/sink X (Connect 와 결합)·매우 큰 분산 어려움
  • vs Spark/Flink — Kafka Streams = 라이브러리 / Spark·Flink = 별도 cluster
  • 선택 — Kafka 안 데이터 + microservice = Kafka Streams / 대규모 분산 ETL = Spark / 매우 낮은 latency = Flink
  • KStream = record stream (이벤트 흐름, append-only)
  • KTable = changelog stream (key 별 최신 값)
  • Stream-Table Duality = 같은 데이터 두 관점, 변환 가능
  • DSL (high-level) = 선언적, 90% 환경 충분
  • Processor API (low-level) = 세밀 제어, custom
  • Topology = Source → Processor → Sink graph
  • Kafka Streams 가 topology 를 task 로 분할 + partition 에 매핑
  • Use Cases = 변환·집계·windowing·join·stateful·interactive queries
  • 학습 로드맵 9편 = Intro·Quickstart·Core Concepts·Write/Run·DSL·Processor·Stateful/IQ·Testing·운영
  • 함정 — Kafka 외 source/sink (Connect 결합)
  • 함정 — 대규모 분산 한계 (Spark/Flink)
  • 함정 — State disk·메모리 비용
  • 함정 — Stateful·windowing·join 학습 곡선
  • 함정 — 운영 특수성 (reprocess·offset·state restore)

공식 문서: Kafka Streams Introduction 에서 자세한 사양을 확인할 수 있어요.

시리즈 다른 편 (앞뒤 글 모음)

이전 글:

다음 글:

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

답글 남기기

error: Content is protected !!