Kafka in Acion 1-3장 발표 자료 정리

Tarte·2026년 3월 24일

기타CS

목록 보기
4/4
post-thumbnail

발표 자료 PPT

Apache Kafka — 실시간 데이터 스트리밍 플랫폼 정리

Kafka in Action 스터디 발표 정리


카프카란

카프카는 분산 스트리밍 플랫폼으로 세 가지 기능을 제공한다.

  • Publish & Subscribe: 메시지 큐처럼 레코드 스트림을 읽고 씀
  • Store: 레코드를 디스크에 복제 저장해 장애 시에도 데이터 보존
  • Process: 데이터 발생 즉시 스트림 처리 애플리케이션으로 가공

기존의 배치 처리 중심(Data at rest) 시스템에서 실시간 흐름 중심(Data in motion) 시스템으로의 전환을 가능하게 하는 것이 핵심이다.


Delivery Semantics — 메시지 전달 보장

카프카는 세 가지 전달 보장 수준을 제공한다.

수준설명특징
At-most-once최대 한 번유실 가능, 중복 없음. 속도가 중요한 로그 수집에 사용
At-least-once최소 한 번유실 없음, 중복 발생 가능. 대부분 시스템의 기본값, 멱등성 처리 필요
Exactly-once정확히 한 번 (조건부)Idempotent Producer + Transaction 지원 시 가능

내부 구조

Append-only Log

카프카의 핵심 저장 구조다.

  • 디스크에 순차적으로만 기록 → 랜덤 IO를 최소화해 높은 쓰기 처리량 달성
  • 읽어도 데이터가 사라지지 않음 (메시지 큐와의 차이)
  • 컨슈머가 자신의 읽은 위치(Offset)를 직접 관리 → 서로 다른 속도로 독립적인 소비 가능
  • 과거 Offset으로 되돌아가 Replay 가능 → 로직 변경 시 유용

Partition

병렬 처리와 순서 보장의 단위다.

  • Leader가 쓰기/읽기를 담당, Follower가 복제
  • ISR(In-Sync Replicas)로 데이터 유실 방지

KRaft (Kafka Raft Metadata)

Kafka 3.3부터 Production-ready, Kafka 4.0에서는 ZooKeeper 모드가 완전 제거됐다.
별도 코디네이터 없이 자체적으로 메타데이터를 관리한다.


고성능 IO 메커니즘

Page Cache 활용

카프카는 JVM 힙 메모리 대신 OS의 페이지 캐시를 적극 사용한다.

  • GC 오버헤드를 줄임
  • 프로세스 재시작 후에도 캐시가 유지됨 (Warm Cache)

Zero-copy 전송

기존 방식(read/write)은 커널 ↔ 유저 공간 간 불필요한 데이터 복사가 발생한다.
카프카는 리눅스의 sendfile() / Java NIO transferTo()를 사용해 커널 영역에서 NIC 버퍼로 직접 전송한다.

기존: Disk → 커널 → 유저 → 커널 → NIC  (4회 복사)
Zero-copy: Disk → 커널 → NIC  (2회로 단축)

CPU 사용량과 컨텍스트 스위칭을 줄여, 디스크 속도가 아닌 네트워크 대역폭이 병목이 되는 수준까지 처리량을 높일 수 있다.

⚠️ SSL/TLS 암호화를 적용하면 데이터가 유저 공간을 거쳐야 하므로 Zero-copy를 사용할 수 없다.


데이터 흐름: Producer → Broker → Consumer

Producer (이벤트 생성)
  └─ Partitioner
       ├─ Key 있음: 해시값으로 파티션 결정
       └─ Key 없음: 라운드 로빈

Broker Cluster (Topic/Partition 저장)
  └─ 각 Partition: Leader(쓰기/읽기) + Follower(복제)

Consumer Group (병렬 처리)
  └─ 같은 Key → 같은 Partition → 순서 보장

Exactly-once 구현 원리 (조건부)

Exactly-once는 마법이 아니다. 아래 세 가지가 결합되어야 성립하는 조건부 보장이다.

1. Idempotent Producer
Producer ID(PID)와 Sequence Number로 브로커가 중복 전송을 감지하고 제거한다.
네트워크 재시도 시에도 중복이 발생하지 않는다.

enable.idempotence=true
acks=all
max.in.flight.requests.per.connection ≤ 5

2. Transactions (2PC)
여러 파티션에 걸친 쓰기 작업을 원자적으로 처리한다.
Transaction Coordinator가 2-Phase Commit 프로토콜로 전체 커밋/롤백을 결정한다.

transactional.id 설정
initTransactions() → commitTransaction()

3. Consumer Isolation
트랜잭션이 성공적으로 커밋된 메시지만 읽는다.
진행 중이거나 실패한(aborted) 트랜잭션의 메시지는 무시한다.

isolation.level = read_committed
(기본값: read_uncommitted)

4. 외부 시스템으로 나가는 경우
카프카 외부(DB, S3 등)로 나가는 경우 카프카만으로는 Exactly-once를 보장할 수 없다.
타겟 시스템의 멱등성 처리나 2PC 지원이 별도로 필요하다.


Rebalancing 심화 & 운영 전략

Rebalance란

컨슈머 그룹 멤버 변경 시 파티션 소유권을 재조정하는 과정이다.
이 동안 Stop-the-world(STW) 가 발생해 일시적으로 메시지 처리가 중단된다.

주요 발생 원인: Consumer 추가/제거, 배포(Rolling Update), Heartbeat 실패

Cooperative Rebalancing (권장)

전체 중단(Eager) 대신 영향을 받는 파티션만 점진적으로 재할당해 STW 시간을 최소화한다.

구분Eager (기존)Cooperative (권장)
동작모든 컨슈머가 일단 멈춤필요한 파티션만 이동
영향전체 처리 중단중단 최소화

Static Membership

컨슈머에 고유 ID를 부여해 재시작 시에도 그룹 탈퇴 없이 멤버십을 유지한다.
Rolling Update 시 불필요한 리밸런싱을 방지한다.

group.instance.id = "consumer-host-1"
session.timeout.ms = 30000+

Offset 관리 & Lag 모니터링

  • Auto Commit: 편하지만 중복/유실 제어가 어려움
  • Manual Commit: 복잡하지만 정확함. 처리 후 커밋 권장

특정 파티션만 Lag가 튄다면 Data Skew나 컨슈머 로직 병목을 의심해야 한다.


Partition & Key 설계 전략

파티션 수 산정

파티션 수는 컨슈머의 최대 병렬 처리 개수를 결정한다.

목표 Throughput ÷ 파티션당 처리량 = 최소 파티션 수
예) 100MB/s ÷ 10MB/s = 최소 10개

레코드 크기, 압축률, 네트워크 대역폭, 디스크 IO를 종합적으로 프로파일링해야 정확하다.
파티션은 늘리기는 쉽지만 줄이기는 어려우므로 초기 설계 시 여유 있게 잡는 게 낫다.

Key 설계

  • 순서 보장: 동일한 Key는 항상 동일한 파티션으로 전송됨 → 사용자 ID를 Key로 쓰면 해당 사용자의 이벤트 순서 보장
  • 분산: 특정 Key에 데이터가 몰리면 Hot Partition 발생 → Key에 난수를 섞거나 Custom Partitioner 고려
  • 카프카는 파티션 내부 순서만 보장하며 전역 순서는 보장하지 않는다

Replay & 장애 대응

  • Offset Reset: 컨슈머 그룹의 Offset을 과거 시점으로 되돌려 재처리. 로직 버그 수정 후 배포 시 유용
  • DLQ (Dead Letter Queue): 처리 실패 메시지를 별도 토픽으로 분리해 메인 파티션의 Lag를 방지하고 나중에 수동 재처리
  • Idempotent Consumer: 재처리 시 중복이 발생하므로 소비 로직은 반드시 멱등성을 보장해야 한다

프로젝트 설계 시 고려할 5가지 질문

  1. 메시지 손실을 허용할 수 있는가? → Delivery Guarantee 수준 결정
  2. 어떤 Key 기준으로 묶을 것인가? → 순서 보장 범위 결정
  3. 순서 보장이 필요한가? → 파티션 설계에 영향
  4. 전체 이력 vs 최신 상태 유지?retention.ms vs cleanup.policy=compact
  5. 몇 개의 Consumer Group이 필요한가? → 파티션 수 하한선 결정

Kafka Connect & 확장 생태계

Kafka Connect

코드를 거의 작성하지 않고도 데이터를 가져오거나 내보낼 수 있는 프레임워크다.

  • Source Connector: DB, 파일 등에서 데이터 수집
  • Sink Connector: S3, Elasticsearch 등으로 데이터 적재

CDC (Change Data Capture)

DB의 변경 사항을 실시간 이벤트 스트림으로 추출한다.
Debezium이 사실상 표준으로 쓰인다.

MySQL Binlog / PostgreSQL WAL / MongoDB Oplog

기존 레거시 DB를 수정하지 않고 MSA 환경으로 데이터를 실시간 동기화하거나, 캐시 갱신 트리거로 활용할 수 있다.

Kafka Streams

별도 클러스터 없이 Java/Scala 애플리케이션 내에서 동작하는 경량 스트림 처리 라이브러리다.

  • State Store 내장으로 join, windowing 지원
  • Exactly-once 처리 지원 (transactional.id)
  • 애플리케이션 배포와 함께 스케일 아웃 가능

ksqlDB

Kafka Streams를 SQL 문법으로 추상화한 스트리밍 DB다.

CREATE STREAM fraud_alert AS
SELECT * FROM payments WHERE amount > 10000;

대시보드용 실시간 집계나 간단한 ETL 파이프라인 구축에 적합하다.


데이터 형식과 스키마 관리

구분JSON (Schemaless)Avro (Schema-based)
스키마 관리없음 (데이터에 필드명 포함)Schema Registry로 중앙 관리
용량 효율낮음 (필드명 반복)높음 (바이너리, 필드명 제외)
타입 안정성약함 (파싱 시점 에러)강함 (컴파일/직렬화 시점 검증)
가독성우수낮음 (바이너리라 도구 필요)

Schema Registry 호환성 전략

  • BACKWARD (기본값): Consumer 먼저 업그레이드. 새 스키마로 구 데이터 읽기 가능
  • FORWARD: Producer 먼저 업그레이드. 구 스키마로 신 데이터 읽기 가능
  • FULL: 순서 상관없음. 양방향 호환성 보장

초기에는 JSON이 편할 수 있지만, 서비스 규모가 커지면 Avro + Schema Registry 조합을 권장한다.
Producer와 Consumer 간의 명확한 데이터 계약(Contract)으로 필드 변경으로 인한 장애를 원천 차단할 수 있다.


운영 필수 체크리스트

  • Rebalancing 전략 (Cooperative + Static Membership)
  • Lag 모니터링
  • 파티션/Key 설계
  • 스키마 관리 (Avro)
profile
기술 블로그

0개의 댓글