Apache Kafka 실무 스터디 가이드

데이터 엔지니어 · AI 엔지니어를 위한 핵심 요약

2026.03 작성 Kafka 4.x (KRaft) 핵심 요약 ~ 15p

목차

  1. Kafka란? — 왜 써야 하는가
  2. 핵심 개념 6가지
  3. 아키텍처 한눈에 보기
  4. KRaft 모드 — ZooKeeper 없는 Kafka
  5. 5분 퀵스타트 (로컬 설치)
  6. Python 프로듀서 / 컨슈머 실습
  7. 핵심 설정값 레퍼런스
  8. 메시지 전달 보장 (Delivery Semantics)
  9. Kafka + AI/ML 파이프라인
  10. 실무 체크리스트 & 트러블슈팅
  11. 참고 자료

1. Kafka란? — 왜 써야 하는가

정의

Apache Kafka는 분산 이벤트 스트리밍 플랫폼이다. LinkedIn에서 처음 개발되었고, 현재 Apache Software Foundation이 관리한다. 단순 메시지 큐가 아니라 실시간 데이터 파이프라인의 중추 신경 역할을 한다.

3대 핵심 능력

Publish / Subscribe

이벤트 스트림을 발행(publish)하고 구독(subscribe). 외부 시스템에서 연속적으로 데이터를 import/export할 수 있다.

Store

이벤트 스트림을 내구성 있게(durably) 원하는 기간만큼 저장. 기본 7일이지만 무제한 보관도 가능.

Process

이벤트가 발생하는 즉시 또는 소급하여(retrospectively) 스트림을 처리할 수 있다.

왜 Kafka를 쓰는가? (vs 전통 MQ)

항목전통 MQ (RabbitMQ 등)Apache Kafka
메시지 수명소비 후 삭제보존 기간 동안 영구 보관 (재소비 가능)
처리량수천 msg/s수백만 msg/s (초당 수 GB)
통신 모델Point-to-Point 중심Pub/Sub + Consumer Group (둘 다)
확장성수직 확장 중심파티션 기반 수평 확장
내구성메모리 중심디스크 기반 + 복제 (fault-tolerant)
순서 보장큐 단위파티션 단위 순서 보장
핵심 포인트

Kafka는 "메시지를 보내고 끝"이 아니라, 이벤트 로그를 중심으로 시스템 전체를 연결하는 데이터 허브로 쓴다. 데이터 엔지니어에게 Kafka는 ETL/ELT 파이프라인의 중추이고, AI 엔지니어에게는 실시간 피처 전달 및 모델 서빙의 백본이다.

대표 유즈케이스

2. 핵심 개념 6가지

Event (Record / Message)

"무언가 일어났다"는 사실의 기록. key, value, timestamp, 그리고 선택적 헤더로 구성된다.

Topic

이벤트가 흐르는 논리적 채널. 파일시스템의 폴더, DB의 테이블과 유사한 개념. 토픽 수에 제한 없음.

Partition

토픽을 물리적으로 분할한 단위. 병렬 처리의 기본 단위이자 저장의 기본 단위. 각 이벤트는 파티션 내에서 고유한 offset을 갖는다.

Broker

Kafka 서버 1대 = 1 Broker. 클러스터는 보통 최소 3대로 구성 (1대 유지보수 + 1대 장애 허용).

Producer

이벤트를 토픽에 쓰는 클라이언트. 어떤 파티션에 보낼지 결정. Consumer와 완전히 디커플링되어 있다.

Consumer / Consumer Group

토픽을 구독하여 이벤트를 읽는 클라이언트. Consumer Group 내에서 각 파티션은 1개의 Consumer에만 할당되어 병렬 소비한다.

토픽-파티션-오프셋 관계도

Topic: "user-events" ┌─────────────────────────────────────────────────────────┐ │ │ │ Partition 0: [0] [1] [2] [3] [4] [5] [6] ──▶ write │ │ Partition 1: [0] [1] [2] [3] [4] ──▶ write │ │ Partition 2: [0] [1] [2] [3] [4] [5] ──▶ write │ │ │ │ ※ 각 파티션 내에서 offset은 절대 재사용되지 않는다 │ │ ※ 파티션 간 순서 보장은 없다 │ └─────────────────────────────────────────────────────────┘

Consumer Group 동작 방식

Topic "orders" (3 partitions) P0 ──▶ Consumer A ┐ P1 ──▶ Consumer B ├── Consumer Group "order-processor" P2 ──▶ Consumer C ┘ P0 ──▶ Consumer X ┐ P1 ──▶ Consumer X ├── Consumer Group "analytics" P2 ──▶ Consumer X ┘ ※ 같은 그룹 내 1개 파티션 = 1개 컨슈머 (병렬 처리) ※ 다른 그룹은 독립적으로 같은 메시지를 읽을 수 있다

Replication (복제)

각 파티션은 여러 브로커에 복제된다. 하나가 Leader(읽기/쓰기 담당), 나머지는 Follower(복제만). Leader 장애 시 Follower 중 하나가 새 Leader로 승격된다.

3. 아키텍처 한눈에 보기

2계층 구조

┌────────────────────────────────────────────────────────────┐ │ COMPUTE LAYER │ │ │ │ Producer API Consumer API Streams API Connect API │ │ │ │ │ │ │ └───────┼───────────────┼─────────────┼─────────────┼────────┘ │ │ │ │ ▼ ▼ ▼ ▼ ┌────────────────────────────────────────────────────────────┐ │ STORAGE LAYER │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ Broker 1 │ │ Broker 2 │ │ Broker 3 │ ... │ │ │ (KRaft │ │ │ │ │ │ │ │ Ctrl) │ │ │ │ │ │ │ └──────────┘ └──────────┘ └──────────┘ │ │ │ │ 분산 커밋 로그 (Distributed Commit Log) │ └────────────────────────────────────────────────────────────┘

5대 핵심 API

API역할사용 시나리오
Producer API이벤트를 토픽에 발행앱 → Kafka 데이터 전송
Consumer API토픽에서 이벤트 구독Kafka → 앱 데이터 소비
Streams API스트림 처리 애플리케이션실시간 변환·집계·윈도잉
Connect API외부 시스템 연동 커넥터DB↔Kafka, S3↔Kafka 등
Admin API토픽·브로커 관리토픽 생성/삭제, 설정 변경

4. KRaft 모드 — ZooKeeper 없는 Kafka

중요 타임라인

Kafka 4.0부터 ZooKeeper 지원이 완전히 제거되었다. 3.9가 ZooKeeper를 지원하는 마지막 버전이며, 2025년 11월부터 ZooKeeper 기반 클러스터는 공식 지원이 종료된다. 지금 새로 시작한다면 무조건 KRaft 모드를 사용해야 한다.

KRaft란?

KRaft(Kafka Raft)는 ZooKeeper를 대체하는 Kafka 자체 내장 메타데이터 관리 프로토콜이다. Raft 합의 알고리즘의 이벤트 기반 변형을 사용하여, 별도 클러스터(ZooKeeper) 없이 Kafka 브로커만으로 메타데이터를 관리한다.

KRaft의 장점

KRaft 모드 설치 (로컬 개발용)

# 1. 클러스터 UUID 생성
KAFKA_CLUSTER_ID="$(bin/kafka-storage.sh random-uuid)"

# 2. 로그 디렉토리 포맷
bin/kafka-storage.sh format \
  -t $KAFKA_CLUSTER_ID \
  -c config/kraft/server.properties

# 3. Kafka 서버 시작 (KRaft 모드)
bin/kafka-server-start.sh config/kraft/server.properties

KRaft 핵심 설정

# config/kraft/server.properties 주요 항목

# 노드 역할: controller, broker, 또는 둘 다 (개발용: controller,broker)
process.roles=broker,controller

# 노드 ID (클러스터 내 고유)
node.id=1

# 컨트롤러 쿼럼 투표자 목록
controller.quorum.voters=1@localhost:9093

# 리스너 설정
listeners=PLAINTEXT://:9092,CONTROLLER://:9093
controller.listener.names=CONTROLLER

# 로그 디렉토리
log.dirs=/tmp/kraft-combined-logs

5. 5분 퀵스타트 (로컬 설치)

사전 요구사항

Java 17 이상이 설치되어 있어야 한다. java -version으로 확인.

Step 1: 다운로드 & 설치

# Kafka 최신 버전 다운로드 (https://kafka.apache.org/downloads)
wget https://downloads.apache.org/kafka/4.0.0/kafka_2.13-4.0.0.tgz
tar -xzf kafka_2.13-4.0.0.tgz
cd kafka_2.13-4.0.0

Step 2: KRaft 모드로 시작

# 클러스터 ID 생성 & 스토리지 포맷
KAFKA_CLUSTER_ID="$(bin/kafka-storage.sh random-uuid)"
bin/kafka-storage.sh format -t $KAFKA_CLUSTER_ID \
  -c config/kraft/server.properties

# Kafka 서버 시작
bin/kafka-server-start.sh config/kraft/server.properties

Step 3: 토픽 생성

# 토픽 생성 (파티션 3개)
bin/kafka-topics.sh --create \
  --topic my-first-topic \
  --bootstrap-server localhost:9092 \
  --partitions 3 \
  --replication-factor 1

# 토픽 목록 확인
bin/kafka-topics.sh --list --bootstrap-server localhost:9092

# 토픽 상세 정보
bin/kafka-topics.sh --describe \
  --topic my-first-topic \
  --bootstrap-server localhost:9092

Step 4: 메시지 생산 & 소비

# 터미널 1: Producer (메시지 입력)
bin/kafka-console-producer.sh \
  --topic my-first-topic \
  --bootstrap-server localhost:9092
> Hello Kafka!
> This is my first event.

# 터미널 2: Consumer (메시지 읽기)
bin/kafka-console-consumer.sh \
  --topic my-first-topic \
  --from-beginning \
  --bootstrap-server localhost:9092
팁

--from-beginning 플래그는 토픽의 처음부터 모든 메시지를 읽는다. 빼면 Consumer 시작 이후의 메시지만 읽는다.

6. Python 프로듀서 / 컨슈머 실습

라이브러리 선택 가이드

라이브러리성능적합한 상황
confluent-kafka최고 (librdkafka 기반 C 래퍼)고부하 프로덕션 환경
kafka-python보통 (순수 Python)중소규모 워크로드, 빠른 프로토타이핑
quix-streams좋음pandas 스타일의 Pythonic 스트림 처리

설치

# confluent-kafka (권장)
pip install confluent-kafka

# 또는 kafka-python
pip install kafka-python

Producer 예제 (confluent-kafka)

from confluent_kafka import Producer
import json

# 설정
conf = {
    'bootstrap.servers': 'localhost:9092',
    'client.id': 'my-python-producer',
    # 성능 튜닝
    'linger.ms': 10,          # 배치 대기 시간
    'batch.size': 16384,      # 배치 크기 (bytes)
    'compression.type': 'lz4' # 압축
}

producer = Producer(conf)

# 전송 콜백
def delivery_callback(err, msg):
    if err:
        print(f'전송 실패: {err}')
    else:
        print(f'전송 성공: {msg.topic()} [{msg.partition()}] @ {msg.offset()}')

# 메시지 전송
for i in range(10):
    event = {'user_id': i, 'action': 'page_view', 'page': f'/products/{i}'}
    producer.produce(
        topic='user-events',
        key=str(i),               # 같은 key → 같은 파티션
        value=json.dumps(event),
        callback=delivery_callback
    )

# 버퍼에 남은 메시지 전송 완료 대기
producer.flush()

Consumer 예제 (confluent-kafka)

from confluent_kafka import Consumer, KafkaError
import json

conf = {
    'bootstrap.servers': 'localhost:9092',
    'group.id': 'my-consumer-group',
    'auto.offset.reset': 'earliest',   # 처음부터 읽기
    'enable.auto.commit': True,         # 자동 오프셋 커밋
    'auto.commit.interval.ms': 5000
}

consumer = Consumer(conf)
consumer.subscribe(['user-events'])

try:
    while True:
        msg = consumer.poll(timeout=1.0)  # 1초 대기

        if msg is None:
            continue
        if msg.error():
            if msg.error().code() == KafkaError._PARTITION_EOF:
                print(f'파티션 끝 도달: {msg.topic()} [{msg.partition()}]')
            else:
                print(f'에러: {msg.error()}')
            continue

        # 메시지 처리
        event = json.loads(msg.value().decode('utf-8'))
        print(f'수신: partition={msg.partition()}, '
              f'offset={msg.offset()}, event={event}')

except KeyboardInterrupt:
    pass
finally:
    consumer.close()  # Consumer Group 탈퇴 & 오프셋 커밋
주의사항

KafkaProducer는 스레드 안전(thread-safe)하지만, KafkaConsumer는 그렇지 않다. Consumer를 멀티스레드로 사용하려면 thread-local로 만들거나, multiprocessing을 권장한다.

7. 핵심 설정값 레퍼런스

Broker 설정

설정기본값설명
num.partitions1토픽 자동 생성 시 기본 파티션 수
default.replication.factor1기본 복제 팩터 (운영: 3 권장)
log.retention.hours168 (7일)메시지 보존 기간
log.segment.bytes1073741824로그 세그먼트 파일 크기 (1GB)
min.insync.replicas1최소 ISR 수 (운영: 2 권장)
auto.create.topics.enabletrue운영에서는 false 권장

Producer 설정

설정기본값설명
acksall0=무확인, 1=리더만, all=ISR 전체
retries2147483647재시도 횟수 (Kafka 3.x+ 기본값 무한)
linger.ms0배치 대기 시간 (높이면 처리량↑, 지연↑)
batch.size16384배치 크기 (bytes)
compression.typenonelz4 또는 zstd 권장
enable.idempotencetrue중복 방지 (exactly-once 기반)

Consumer 설정

설정기본값설명
group.id-Consumer Group 식별자 (필수)
auto.offset.resetlatestearliest=처음부터, latest=최신부터
enable.auto.committrue오프셋 자동 커밋 여부
max.poll.records500poll() 당 최대 레코드 수
session.timeout.ms45000Consumer 생존 감지 타임아웃
fetch.min.bytes1fetch 최소 바이트 (높이면 처리량↑)

8. 메시지 전달 보장 (Delivery Semantics)

수준설정특징
At-Most-Once acks=0 메시지 손실 가능. 처리량 최대. 로그/메트릭 등 손실 허용 가능한 경우.
At-Least-Once acks=all + 재시도 메시지 중복 가능. 대부분의 운영 환경 기본값. Consumer 측 멱등성 필요.
Exactly-Once enable.idempotence=true + 트랜잭션 API 중복·손실 없음. 결제 등 정확성 필수 시나리오. 약간의 성능 오버헤드.

운영 권장 조합

# Producer: 안전한 기본값
acks=all
enable.idempotence=true
max.in.flight.requests.per.connection=5
retries=2147483647

# Broker: 데이터 안전성
min.insync.replicas=2
unclean.leader.election.enable=false

# Consumer: 수동 커밋으로 정확한 처리
enable.auto.commit=false
# → 메시지 처리 완료 후 consumer.commit() 호출
실무 팁

대부분의 데이터 파이프라인은 At-Least-Once + Consumer 측 멱등성(Idempotency)이 현실적 최선이다. Exactly-Once는 Kafka Streams 내부 처리에서 가장 쉽게 달성할 수 있다.

9. Kafka + AI/ML 파이프라인

왜 AI 파이프라인에 Kafka가 필요한가?

대부분의 AI 실패는 모델 정확도 문제가 아니라 데이터 파이프라인 병목에서 온다. 배치 파이프라인으로 실시간 예측을 서빙하려는 것이 근본 원인이다. Kafka는 이 문제를 해결하는 실시간 데이터 백본이다.

핵심 아키텍처 패턴

┌──────────┐ ┌──────────┐ ┌──────────────┐ ┌──────────┐ │ 데이터 │ │ Kafka │ │ 스트림 처리 │ │ ML 모델 │ │ 소스 │──▶│ Cluster │──▶│ (Flink/ │──▶│ 서빙 │ │ │ │ │ │ Spark) │ │ │ │ - DB CDC │ │ │ │ │ │ - 추론 │ │ - API │ │ │ │ - 피처 추출 │ │ - 예측 │ │ - IoT │ │ │ │ - 집계 │ │ - 스코어 │ │ - 로그 │ │ │ │ - 변환 │ │ │ └──────────┘ └──────────┘ └──────────────┘ └──────────┘ │ │ ▼ ▼ ┌──────────────┐ ┌──────────┐ │ Feature Store │ │ 결과 │ │ (Redis/ │ │ Topic │ │ DynamoDB) │ │ │ └──────────────┘ └──────────┘

실무 시나리오별 적용

시나리오Kafka 역할ML 모델
실시간 사기 탐지 거래 이벤트 스트림 수집, 사용자 프로필 데이터와 enrichment 트랜잭션 스코어링 모델이 실시간으로 승인/차단 결정
고객 이탈 예측 로그인/활동/취소 이벤트 스트림 세션 데이터 집계 → 이탈 확률 예측 → CRM 자동 리텐션 트리거
동적 가격 책정 경쟁사 가격, 브라우징 행동, 재고 데이터 스트림 강화학습 모델이 실시간 가격 조정 추천
실시간 추천 사용자 클릭/조회/구매 이벤트 실시간 피처 업데이트 → 추천 모델 서빙 → 결과를 Kafka로 전달

Kafka-ML 프레임워크

Kafka-ML은 Kafka의 고처리량·저지연 특성을 활용하여 ML/AI 파이프라인을 관리하는 오픈소스 프레임워크다. TensorFlow와 PyTorch를 지원하며, 연속적인 데이터 스트림에서 동작하는 ML 시스템 구축에 특화되어 있다.

모델 드리프트 대응

Kafka + Flink 조합으로 온라인 ML 학습과 모델 드리프트 감지를 구현할 수 있다. 연속적인 모델 훈련과 실시간 추론을 통해 항상 최신 상태의 고정확도 예측을 유지할 수 있다.

간단한 예제: Kafka → ML 추론

from confluent_kafka import Consumer, Producer
import json, pickle

# 학습된 모델 로드
model = pickle.load(open('fraud_model.pkl', 'rb'))

consumer = Consumer({
    'bootstrap.servers': 'localhost:9092',
    'group.id': 'ml-inference',
    'auto.offset.reset': 'latest'
})
consumer.subscribe(['transactions'])

producer = Producer({'bootstrap.servers': 'localhost:9092'})

while True:
    msg = consumer.poll(1.0)
    if msg is None or msg.error():
        continue

    # 1. 이벤트 파싱
    event = json.loads(msg.value().decode('utf-8'))

    # 2. 피처 추출
    features = extract_features(event)  # 사용자 정의 함수

    # 3. 모델 추론
    prediction = model.predict([features])[0]
    score = model.predict_proba([features])[0][1]

    # 4. 결과를 다른 토픽에 발행
    result = {
        'transaction_id': event['id'],
        'is_fraud': bool(prediction),
        'fraud_score': float(score)
    }
    producer.produce(
        'fraud-results',
        key=str(event['id']),
        value=json.dumps(result)
    )
    producer.flush()

10. 실무 체크리스트 & 트러블슈팅

프로덕션 배포 전 체크리스트

항목권장값이유
Broker 수최소 3대1대 유지보수 + 1대 장애 허용
replication.factor3데이터 안전성
min.insync.replicas2쓰기 확인 최소 수
acksall데이터 손실 방지
파티션 수Consumer 수 × 2~3배병렬성 확보
auto.create.topicsfalse의도치 않은 토픽 생성 방지
unclean.leader.electionfalseISR 밖의 리더 선출 방지
compression.typelz4 또는 zstd네트워크/디스크 절약

자주 겪는 문제 & 해결

Consumer Lag 증가

Rebalancing이 너무 자주 발생

메시지 순서가 뒤바뀜

디스크 부족

모니터링 필수 메트릭

메트릭위치알람 기준
Consumer LagConsumer Group지속적으로 증가하면 위험
Under-Replicated PartitionsBroker0이 아니면 즉시 확인
ISR Shrink/Expand RateBroker빈번하면 네트워크/디스크 문제
Request Latency (p99)Broker급증 시 브로커 부하 확인
Disk UsageBroker80% 초과 시 경고
모니터링 도구

Kafka 메트릭은 JMX로 노출된다. Prometheus + Grafana 조합이 가장 널리 사용되며, Confluent Control Center(유료) 또는 AKHQ(오픈소스 UI)도 좋은 선택이다.

참고 자료