Data & AI

Kafka 기초

meellon 2026. 7. 5. 20:30

학습 목표

topic·partition·offset으로 Kafka 로그 모델을 설명할 수 있다.

partition keyordering 범위를 설계할 수 있다.

consumer group으로 병렬 소비·lag를 이해할 수 있다.

retention·replay로 backfill·재처리 경로를 설계할 수 있다.

앞 편 ingest 레이어에서 Kafka가 어떤 역할인지 연결할 수 있다.

문제 상황

  • 앱이 DB에 직접 INSERT — 피크에 WAL·lock 포화, 분석 쿼리와 경합
  • RabbitMQ로 이벤트 보냈는데 한 consumer만 — 처리량 천장, 메시지 유실 걱정
  • “Kafka 썼다” — topic 하나에 파티션 1개, consumer 10개인데 9개 idle
  • order_id 순서가 중요한데 전역 순서를 기대 — partition 설계 미스
  • retention 7일인데 한 달 전 데이터 재처리 필요 — replay 방법을 모름
  • 3편에서 unbounded ingest에 Kafka가 나왔지만 — topic·group 개념이 없음

이번 편은 스트림 ingest의 표준 버퍼 — Kafka 로그 모델과 확장·순서·재처리 설계다. Spark로 처리하는 방법은 5~6편.

1. Kafka가 ingest에 쓰이는 이유

앞 편 data plane에서 ingest는 소스와 process 사이 버퍼다. Kafka는 그 역할의 대표 구현이다.

역할 Kafka가 해주는 것
Decouple producer·consumer 속도·장애 분리
Buffer burst 흡수, downstream 처리 지연 허용
Durability 디스크 복제 로그 — broker 재시작 후 복구
Fan-out 같은 topic을 여러 consumer group이 독립 소비
Replay retention 내 offset 되감기 — backfill·재처리
App / CDC ──► Kafka topic ──► Spark streaming
                         ├──► warehouse sink (Connect)
                         └──► fraud detector (another group)
  • Message queue와 다름 — consumer가 읽어도 로그 삭제 안 됨 (retention까지 보관)
  • ELK — 로그 검색 축; Kafka는 분석·처리이벤트 버스
  • Database CDC — Debezium 등이 change event를 topic에 append
  • Kafka 없이도 ingest 가능 — 파일 landing·Kinesis 등 — 원리는 버퍼·내구·fan-out

2. Topic · Partition · Offset

Kafka 데이터는 topic 아래 partition 로그append-only로 쌓인다.

개념 정의
Topic 논리 스트림 이름 (예: orders.events)
Partition topic을 나눈 순서 로그 — 병렬 단위
Offset partition 내 순번 (0, 1, 2, …) — 불변
Broker partition 복제본저장하는 서버
topic: orders.events
  partition 0: [o0][o1][o2]...   offsets 0..N
  partition 1: [o0][o1]...       offsets 0..M
  partition 2: [o0][o1][o2][o3]...
  • Append-only — 기존 레코드 수정·삭제 없음 (compact topic은 기준 예외, §5)
  • Partition 수 — topic 생성 시 정함 — 늘리기는 가능, 줄이기는 사실상 불가
  • Throughput — partition마다 순서 I/O — partition 많을수록 쓰기·읽기 병렬
  • Replication — partition leader + followerreplication.factor내구 (운영)

3. Ordering과 Partition Key

순서partition 안에서만 보장된다. 전 topic 전역 순서는 기대하지 않음.

설계 key 순서 보장
주문 상태 order_id 같은 주문 이벤트 순서
사용자 클릭 user_id 같은 사용자 내 순서
순서 무관 null / random 라운드로빈 — 최대 throughput
전역 순서 필요 partition 1개 병렬성 0 — 흔히 피함
# code/producer_partition_key.py (발췌)
producer.send(
    topic="orders.events",
    key=str(order_id).encode(),      # same key → same partition
    value=json.dumps(event).encode(),
)
# hash(key) % num_partitions → partition id
  • Hot partition — key 편향 (대형 tenant) → 한 partition만 포화
  • Key 없음 — producer가 round-robin — 순서 없음, 균등 분산
  • Ordering vs scale — 필요한 최소 key 범위만 순서 — 나머지는 partition 늘림
  • Downstream — Spark·Flink도 같은 keyshuffle·state — ingest 설계와 맞춤

4. Consumer Group

Consumer group같은 group.id를 쓰는 consumer들이 partition을 나눠 읽는다.

개념 의미
Group group.id 논리 consumer
Assignment partition 1개는 group 내 최대 1 consumer
Rebalance consumer 추가·제거 시 partition 재할당
Lag log end offset − consumer offset — 처리 지연
topic 6 partitions, group "spark-orders":
  C1 ← P0, P1
  C2 ← P2, P3
  C3 ← P4, P5

group "warehouse-sink" (별도): 같은 topic, 독립 offset
  • Parallelism 상한 — consumer 수 ≤ partition 수 (초과 consumer는 idle)
  • 다른 group독립 offset — warehouse·fraud·debug 동시 소비
  • At-least-once — offset commit crash → 재처리 (멱등 sink 필요, 이후 편)
  • Rebalance — 처리 중 stop-the-worldcooperative sticky assignor로 완화 (운영)
# code/consumer-group.yaml (발췌)
consumer:
  group.id: spark-orders-v2
  enable.auto.commit: false        # process 후 manual commit
  max.poll.records: 500
  session.timeout.ms: 45000
monitoring:
  alert: consumer_lag > 100000 for 15m

5. Retention · Replay

로그는 retention 정책까지 디스크에 남는다. 삭제가 아니라 만료다.

정책 설정 용도
Time retention retention.ms (예: 7d) 이벤트 원본 보관
Size retention retention.bytes 디스크 상한
Compact cleanup.policy=compact 최신 값 (CDC snapshot)
Replay seek(offset) / reset backfill·버그 수정 후 재처리
Day 1 ──► events append ──► Day 7 retention expires old segments
Bug fix ──► new consumer group OR seek to offset 0 ──► reprocess
  • Replay ≠ 무한 — retention 넘으면 데이터 삭제 — 장기 원본은 lake (S3)
  • Kappa (3편) — topic retention + replay로 배치 대체lake병행 흔함
  • Compact topicuser_id → profile 최신만 — changelog·CDC 메타
  • Tiered storage — 오래된 segment object storage — 비용·retention 연장 (운영)

6. Topic 설계 체크리스트

# 질문
1 어떤 key로 순서가 필요한가
2 partition 수가 peak throughput·consumer 병렬에 맞는가
3 consumer lag SLA·알림이 있는가
4 retention이 replay·backfill 요구를 커버하는가
5 장기 원본은 lake로 offload하는가
6 여러 downstream이 별도 group으로 fan-out되는가
# code/topic-design.yaml (발췌)
topics:
  - name: orders.events
    partitions: 12
    replication.factor: 3
    config:
      retention.ms: 604800000          # 7 days
      min.insync.replicas: 2
    key: order_id                      # ordering per order
    consumers:
      - group: spark-streaming-orders
      - group: warehouse-connect-sink

정리

  • Kafka — ingest 버퍼·decouple·fan-out·replay
  • Topic / partition / offset — append-only 로그, 순서는 partition 단위
  • Partition key — 필요한 범위만 ordering, hot partition 주의
  • Consumer group — partition 분할 소비, lag = 처리 지연
  • Retention — replay ; 장기 보관은 lake

다음에 다룰 것

  • Spark 배치 처리
  • RDD·DataFrame, shuffle, partition, action vs transformation

해당 내용은 Kleppmann — Designing Data-Intensive Applications, Confluent Kafka Core concepts 를 기반으로 합니다.

'Data & AI' 카테고리의 다른 글

Spark Structured Streaming  (0) 2026.07.13
Spark 배치 처리  (0) 2026.07.09
Batch vs Stream  (0) 2026.07.03
데이터 규모와 아키텍처  (0) 2026.07.02
Data · AI 오리엔테이션  (0) 2026.07.01