기본개념 · 1장
Kafka 개요와 이벤트 스트리밍
Apache Kafka는 이벤트를 발행·구독하고, 원하는 기간만큼 durable하게 저장하고, 실시간 또는 사후에 처리하는 세 가지 일을 한 시스템에서 처리합니다. 이 장에서는 그 세 가지가 왜 한 묶음이어야 했는지, 전통적 메시지 큐와 무엇이 다른지, 그리고 이후 10개 장에서 계속 쓰게 될 토픽·파티션·오프셋 어휘를 정리합니다.
학습 목표
- 이벤트 스트리밍이 해결하는 문제를 설명하고, 전통적 메시지 큐와 분산 커밋 로그의 차이를 구분할 수 있습니다.
- 토픽 · 파티션 · 오프셋 · 레플리카의 관계를 그림 없이도 설명할 수 있습니다.
- Producer · Consumer · Connect · Streams · Schema Registry가 각각 어떤 역할을 맡는지 구분할 수 있습니다.
kafka_2.13-4.3.0같은 배포 파일명을 읽고,2.13이 Kafka 버전이 아님을 설명할 수 있습니다.
왜 Kafka인가 — 메시지 큐가 아니라 로그입니다
시스템이 늘어나면 데이터 이동 경로가 곱셈으로 늘어납니다. 주문 서비스가 재고·정산·알림·분석에 각각 직접 연결하면 연결선은 서비스 수의 곱에 비례해 늘고, 새 소비자를 추가할 때마다 생산자 쪽을 고쳐야 합니다. Kafka는 그 사이에 durable한 로그를 하나 두어 생산자와 소비자를 완전히 분리합니다. 공식 문서는 이를 세 가지 능력의 조합으로 정의합니다.
- 이벤트 스트림을 발행(publish)하고 구독(subscribe)한다.
- 이벤트 스트림을 원하는 기간만큼 durable하고 신뢰성 있게 저장한다.
- 이벤트 스트림을 발생 시점에 또는 사후에 처리한다.
두 번째 항목이 전통적 메시지 큐와 결정적으로 다른 지점입니다. Kafka에서 이벤트는 소비되어도 삭제되지 않습니다. 보관 기간은 토픽별 설정으로 정하고, 그 기간이 지난 이벤트만 버려집니다. 읽기 위치는 브로커가 아니라 소비자 쪽 오프셋이 결정하므로, 같은 데이터를 여러 소비자가 각자의 속도로, 필요하면 처음부터 다시 읽을 수 있습니다.
비교표
| 관점 | 전통적 메시지 큐 | Kafka (분산 커밋 로그) |
|---|---|---|
| 소비 후 데이터 | 큐에서 제거됨 | 보관 기간까지 그대로 남음 |
| 읽기 위치 관리 | 브로커가 각 메시지의 배달 상태를 추적 | 소비자 그룹의 오프셋으로 관리 |
| 재처리 | 일반적으로 불가 (별도 보관 필요) | 오프셋을 되돌려 다시 읽으면 됨 |
| 다중 소비자 | 같은 메시지를 여러 소비자에게 주려면 팬아웃 구조 필요 | 소비자 그룹마다 독립적으로 전체를 읽음 |
| 순서 보장 단위 | 큐 전체 또는 없음 | 파티션 단위로 보장 |
| 확장 방식 | 큐/브로커 추가 | 파티션 추가 → 생산·소비 병렬성 증가 |
핵심 추상 — 이벤트, 토픽, 파티션, 오프셋
토픽과 파티션
이벤트는 토픽(topic)에 저장됩니다. 토픽은 파일시스템의 폴더에 가깝고, 이벤트가 그 안의 파일에 해당합니다. 토픽은 항상 다중 생산자·다중 구독자이며, 생산자 0개 이상, 소비자 0개 이상이 붙을 수 있습니다.
토픽은 여러 파티션(partition)으로 쪼개져 서로 다른 브로커에 배치됩니다. 이 분산 배치가 확장성의 근거입니다. 클라이언트가 여러 브로커에 동시에 읽고 쓸 수 있기 때문입니다. 새 이벤트를 토픽에 발행하면 실제로는 그중 한 파티션의 끝에 append됩니다.
같은 키를 가진 이벤트는 같은 파티션에 기록됩니다. 그리고 Kafka는 특정 토픽-파티션의 소비자가 그 파티션의 이벤트를 기록된 순서 그대로 읽는 것을 보장합니다. 순서 보장이 파티션 단위인 이유가 여기 있습니다. 주문 ID를 키로 쓰면 그 주문의 상태 변화가 뒤바뀌지 않습니다. 키를 지정하지 않으면 순서 보장의 근거 자체가 사라집니다 — 이 실수의 결과는 케이스 4에서 다룹니다.
오프셋 — 파티션 안의 좌표
오프셋(offset)은 파티션 안에서 레코드의 위치를 나타내는 단조 증가 정수입니다. 파티션에 append될 때 부여되고, 이후 변하지 않습니다. 오프셋은 파티션 안에서만 의미가 있습니다. 토픽 전체를 가로지르는 전역 오프셋은 존재하지 않습니다.
실무와 시험에서 가장 많이 혼동되는 것은 오프셋이 한 종류가 아니라는 점입니다. 하나의 파티션 로그 위에 최소 네 개의 서로 다른 지점이 동시에 존재합니다. 아래 다이어그램의 슬라이더를 움직여 이 네 지점이 어떻게 벌어지는지 확인해 보세요. 복제·ISR과 함께 보는 상세한 설명은 2장 아키텍처와 핵심 개념에 있습니다.
log-start-offset · committed offset · high watermark · LEO.
슬라이더로 팔로워 복제 진행과 컨슈머 커밋을 움직이면, high watermark가 ISR 내 최소 LEO로 결정되고
컨슈머가 그 이상을 읽을 수 없다는 점이 드러납니다.
복제 — 파티션 단위로 복사됩니다
내구성과 가용성은 복제(replication)로 확보합니다. 복제 단위는 토픽이 아니라 토픽-파티션입니다. 공식 문서는 프로덕션에서 흔히 쓰이는 설정으로 복제 계수(replication factor) 3을 예로 듭니다. 즉 같은 파티션의 사본이 항상 3개 존재합니다. 파티션마다 리더 하나와 팔로워 0개 이상이 있고, 쓰기는 리더로 갑니다.
이 장에서 나온 설정
| 설정 | 기본값 | 설명 | 튜닝 포인트 |
|---|---|---|---|
num.partitionsbroker |
1 | 자동 생성 토픽의 기본 파티션 수 | 소비 병렬성의 상한이 됩니다. 토픽을 명시 생성해 직접 지정하세요. |
default.replication.factorbroker |
1 | 자동 생성 토픽의 기본 복제 계수 | 1이면 브로커 한 대만 잃어도 데이터가 사라집니다. |
auto.create.topics.enablebroker |
true | 존재하지 않는 토픽으로의 요청 시 자동 생성 | 오타 토픽이 조용히 만들어집니다. 운영 클러스터에서는 끄는 편이 안전합니다. |
retention.mstopic |
604800000 (7일) |
delete 정책에서 로그를 보관하는 최대 시간 |
재처리 여유 기간을 결정합니다. 삭제는 세그먼트 단위로 일어납니다(7장). |
cleanup.policytopic |
delete | delete 또는 compact (조합 가능) |
상태 저장 토픽에 delete가 남아 있으면 데이터가 사라집니다(케이스 8). |
message.max.bytesbroker |
1048588 | Kafka가 허용하는 최대 레코드 배치 크기(압축 후 기준) | 토픽 레벨 max.message.bytes가 오버라이드합니다. 프로듀서·컨슈머 설정과 함께 맞춰야 합니다(케이스 10). |
Kafka 생태계와 5개 API
Kafka는 서버(브로커)와 클라이언트가 TCP 기반 자체 프로토콜로 통신하는 분산 시스템입니다. 서버 일부는 저장 계층인 브로커를 이루고, 다른 일부는 Kafka Connect를 실행해 외부 시스템과 데이터를 주고받습니다. 공식 문서는 Java·Scala용 핵심 API를 다섯 개로 정리합니다.
| API | 역할 | 이 가이드의 담당 장 |
|---|---|---|
| Admin API | 토픽·브로커 등 Kafka 객체 관리와 조회 | 11장, CLI 치트시트 |
| Producer API | 하나 이상의 토픽에 이벤트 스트림을 발행 | 4장 |
| Consumer API | 하나 이상의 토픽을 구독하고 이벤트를 처리 | 5장 |
| Kafka Streams API | 변환·집계·조인·윈도우·이벤트 시간 처리를 제공하는 스트림 처리 라이브러리 | 10장 |
| Kafka Connect API | 외부 시스템과의 재사용 가능한 import/export 커넥터 | 9장 |
Schema Registry와 ksqlDB는 Apache Kafka 본체가 아니라 Confluent가 제공하는 별도 컴포넌트입니다. CCDAK 출제 범위에는 Schema Registry가 포함되므로 이 가이드도 8장에서 다룹니다.
클라이언트는 어떻게 클러스터를 찾는가
클라이언트는 bootstrap.servers에 적힌 host:port 목록으로 최초 연결을 맺고,
그 연결로 메타데이터를 받아 클러스터 전체를 알아냅니다.
공식 문서는 이 목록에 전체 브로커를 적을 필요가 없다고 명시하면서도,
일부 서버가 죽어 있을 때를 대비해 여러 개를 적으라고 권고합니다.
부트스트랩 지점이 하나뿐입니다. 이 브로커가 재시작 중이면 클러스터가 정상인데도 클라이언트가 붙지 못합니다.
bootstrap.servers=kafka-1.internal:9092
초기 연결 지점을 이중화했습니다. 하나만 붙으면 나머지 브로커는 메타데이터로 알아내므로, 전체 목록을 적을 필요는 없습니다.
bootstrap.servers=kafka-1.internal:9092,kafka-2.internal:9092,kafka-3.internal:9092
Kafka 버전 표기 읽는 법 — 2.13은 Kafka 버전이 아닙니다
Kafka 배포 파일명은 두 개의 버전 번호를 한 줄에 담고 있어서 매우 흔하게 오해를 일으킵니다.
Apache 아카이브의 4.3.1 디렉터리에는 kafka_2.13-4.3.1.tgz 하나만 올라와 있습니다.
kafka_2.13-4.3.1.tgz
──── ─────
Scala Kafka
2.13 4.3.1
kafka_2.13-4.3.0.tgz의 각 부분이 무엇을 의미하는지 지시선으로 분해
| 표기 | 의미 |
|---|---|
kafka_2.13 | Scala 2.13으로 컴파일된 배포판. 현행 Kafka가 제공하는 유일한 Scala 버전 |
-4.3.1 | Apache Kafka 버전 |
_2.12 | 과거 배포판에 있던 Scala 2.12 빌드. 현행 Kafka에서는 제공되지 않습니다 |
kafka-4.3.1-src.tgz | 소스 배포판 (Scala 접두어가 없습니다) |
내려받은 뒤 클러스터를 처음 띄우는 절차는 공식 quickstart와 같습니다. KRaft에서는 클러스터 UUID를 만들고 로그 디렉터리를 포맷한 뒤 브로커를 기동합니다. 동작하는 3노드 구성은 예제 1에서 다룹니다.
tar -xzf kafka_2.13-4.3.1.tgz
cd kafka_2.13-4.3.1
# 1. 클러스터 UUID 생성
KAFKA_CLUSTER_ID="$(bin/kafka-storage.sh random-uuid)"
# 2. 로그 디렉터리 포맷 (KRaft 필수 단계)
bin/kafka-storage.sh format --standalone -t $KAFKA_CLUSTER_ID -c config/server.properties
# 3. 기동
bin/kafka-server-start.sh config/server.properties
# 4. 토픽 생성 — 항상 --bootstrap-server 를 씁니다
bin/kafka-topics.sh --create --topic quickstart-events --bootstrap-server localhost:9092
bin/kafka-topics.sh --describe --topic quickstart-events --bootstrap-server localhost:9092
대표 사용 사례 4가지
공식 문서가 드는 사례들을 이 가이드의 학습 경로와 묶어 정리했습니다.
| 사례 | Kafka가 맡는 역할 | 주의할 지점 |
|---|---|---|
| 결제·금융 트랜잭션 실시간 처리 | 주문/결제 이벤트를 순서 보장하며 여러 소비자에게 전달 | 중복 처리 방지가 필수. Kafka 내부 EOS와 외부 시스템 멱등성은 다른 문제입니다(6장) |
| IoT · 센서 데이터 수집 | 고빈도 측정값을 durable하게 수집하고 사후 재처리 허용 | 메시지 크기와 보관 용량 산정(7장) |
| 데이터베이스 변경 캡처(CDC)와 통합 | Connect로 DB 변경을 스트림화해 여러 목적지에 공급 | source와 sink의 오프셋 저장 위치가 다릅니다(9장) |
| 이벤트 기반 마이크로서비스 | 서비스 간 결합을 로그로 분리하고, 상태를 스트림으로 재구성 | KStream과 KTable 중 무엇이 맞는 모델인지 판단(10장) |
Kafka 4.x가 이전과 다른 점
이 가이드는 Apache Kafka 4.3.x를 기준으로 서술합니다. 시중 한국어 자료 대부분이 2.x/3.x(ZooKeeper 시대) 기준이므로, 특히 아래 세 가지는 예전 자료를 그대로 따라 하면 동작하지 않습니다.
흔한 오해
시험 포인트
확인 문제
네 가지 문항 유형(단일 선택 · 복수 선택 · 연결형 · 순서 배열)이 섞여 있습니다. 실제 CCDAK/CCAAK 시험에도 matching과 list order 유형이 출제되므로 함께 연습하세요. 키보드만으로 완주할 수 있습니다 — 숫자키로 선택, Enter로 제출입니다.
이어서 볼 곳
- 2장 · 아키텍처와 핵심 개념 파티션·세그먼트·복제·ISR과 오프셋 4종을 정확히 정리합니다.
- 부록 · 버전 표기와 레거시 2.x/3.x 운영, 버전 타임라인, 2.x → 3.9 → 4.x 업그레이드 경로.
- CLI 치트시트 목적별 명령 표. 다운로드·설치 표기 주의사항 포함.
- CCDAK 개요 · 4주 학습 플랜 도메인 블루프린트와 챕터 매핑, 진단 테스트로 시작하는 학습 순서.
- 진단 테스트 30문항으로 6개 도메인 취약점을 진단하고 학습 순서를 자동 생성합니다.
- 예제 1 · 로컬 KRaft 클러스터 docker-compose로 ZooKeeper 없는 3노드 클러스터를 띄웁니다.
공식 문서 출처
이 장의 설정 기본값과 버전 사실은 모두 아래에서 확인했습니다 (Apache Kafka 4.3.1 문서 기준).
- Apache Kafka Documentation — Getting Started / Introduction — 이벤트 스트리밍 정의, 토픽·파티션·복제, 5개 API
- Broker Configs —
num.partitions,default.replication.factor,auto.create.topics.enable,message.max.bytes - Topic Configs —
retention.ms,cleanup.policy - Producer Configs —
bootstrap.servers,max.request.size - Consumer Configs —
group.protocol기본값classic - Upgrading Apache Kafka — 4.3 업그레이드 요건, Share Groups(KIP-932) 4.2 production-ready
- Consumer Rebalance Protocol — KIP-848 GA, 서버/클라이언트 활성화 방식
- Java Version — Java 17 · 21 · 25 완전 지원, Java 11은 일부 모듈
- Quickstart —
kafka-storage.sh random-uuid/format/ 기동 순서 - Downloads —
kafka_2.13-4.3.1.tgz(Scala 2.13 단일 배포)