카프카 클러스터 구축 실습 — Zookeeper + 브로커 3대
docker-compose로 Zookeeper 기반 카프카 브로커 3대를 직접 띄우고, 토픽을 만들어 Leader/Replicas/ISR이 실제로 어떻게 배치되는지, 프로듀서/컨슈머 처리량은 어느 정도 나오는지 확인해본 실습 노트입니다.
카프카 클러스터 구축 실습 — Zookeeper + 브로커 3대
카프카 구성: Zookeeper(관리자) + Broker(일꾼)
카프카 클러스터는 크게 두 역할로 나뉩니다.
- Zookeeper: 브로커들을 관리하고 상태를 체크하는 관리자 역할
- Broker: 실제로 데이터를 저장하고 처리하는 일꾼 역할
브로커 3대짜리 클러스터를 docker-compose로 직접 띄워봤습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
services:
zookeeper:
image: confluentinc/cp-zookeeper:7.5.0
container_name: zookeeper
environment:
ZOOKEEPER_CLIENT_PORT: 2181
ZOOKEEPER_TICK_TIME: 2000
kafka-1:
image: confluentinc/cp-kafka:7.5.0
container_name: kafka-1
depends_on:
- zookeeper
ports:
- "9091:9091"
environment:
KAFKA_BROKER_ID: 1
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka-1:29092,PLAINTEXT_HOST://localhost:9091
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
kafka-2:
image: confluentinc/cp-kafka:7.5.0
container_name: kafka-2
depends_on:
- zookeeper
ports:
- "9092:9092"
environment:
KAFKA_BROKER_ID: 2
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka-2:29092,PLAINTEXT_HOST://localhost:9092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
kafka-3:
image: confluentinc/cp-kafka:7.5.0
container_name: kafka-3
depends_on:
- zookeeper
ports:
- "9093:9093"
environment:
KAFKA_BROKER_ID: 3
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka-3:29092,PLAINTEXT_HOST://localhost:9093
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
KAFKA_LISTENERS는 따로 지정하지 않았는데, Confluent 이미지가 KAFKA_ADVERTISED_LISTENERS의 호스트명을 0.0.0.0으로 바꿔서 자동으로 유추해줍니다 — kafka-1은 컨테이너 안에서 0.0.0.0:29092(브로커 간 통신용)와 0.0.0.0:9091(호스트 접속용)에 바인딩되고, ports: "9091:9091" 매핑과 맞물려 정상 동작합니다.
클러스터 가동
1
2
docker compose up -d
docker compose ps
브로커 3개가 정상 등록됐는지는 Zookeeper에서 확인할 수 있습니다.
1
docker exec -it zookeeper zookeeper-shell localhost:2181 ls /brokers/ids
1
2
3
4
5
6
Connecting to localhost:2181
WATCHER::
WatchedEvent state:SyncConnected type:None path:null
[1, 2, 3]
토픽 생성과 Leader / Replicas / ISR
파티션 3개, 복제 계수 3으로 토픽을 만들었습니다.
1
2
3
4
5
6
docker exec -it kafka-1 kafka-topics \
--create \
--topic my-first-topic \
--partitions 3 \
--replication-factor 3 \
--bootstrap-server kafka-1:29092
메시지를 보내고 받는 것도 확인했습니다.
1
2
3
4
5
6
7
8
9
10
# 보내기
docker exec -it kafka-1 kafka-console-producer \
--topic my-first-topic \
--bootstrap-server kafka-1:29092
# 받기
docker exec -it kafka-1 kafka-console-consumer \
--topic my-first-topic \
--from-beginning \
--bootstrap-server kafka-1:29092
토픽 상세 정보를 보면 파티션마다 리더/복제본이 어떻게 배치됐는지 나옵니다.
1
2
3
4
docker exec -it kafka-1 kafka-topics \
--describe \
--topic my-first-topic \
--bootstrap-server kafka-1:29092
1
2
3
4
Topic: my-first-topic TopicId: N6vqMROxTDCzi3DDzStPWw PartitionCount: 3 ReplicationFactor: 3 Configs:
Topic: my-first-topic Partition: 0 Leader: 2 Replicas: 2,3,1 Isr: 2,3,1
Topic: my-first-topic Partition: 1 Leader: 3 Replicas: 3,1,2 Isr: 3,1,2
Topic: my-first-topic Partition: 2 Leader: 1 Replicas: 1,2,3 Isr: 1,2,3
- Leader: 실제 읽기/쓰기가 일어나는 브로커. 파티션 0번은 브로커 2, 파티션 1번은 브로커 3, 파티션 2번은 브로커 1이 리더입니다.
- Replicas: 데이터가 복제되어 저장된 브로커 목록.
- ISR(In-Sync Replicas): 리더와 완전히 동기화된 복제본 목록. 브로커가 3대, 복제 계수도 3이라 모든 파티션이 브로커 3대 전부에 복제되고, ISR도 Replicas와 완전히 일치하는 상태입니다.
프로듀서/컨슈머 성능 테스트
카프카에 내장된 성능 테스트 도구로 처리량을 확인했습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
# 프로듀서: 1KB 크기 메시지 10만 개
docker exec -it kafka-1 kafka-producer-perf-test \
--topic my-first-topic \
--num-records 100000 \
--record-size 1024 \
--throughput -1 \
--producer-props bootstrap.servers=kafka-1:29092
# 컨슈머: 10만 개 소비
docker exec -it kafka-1 kafka-consumer-perf-test \
--topic my-first-topic \
--messages 100000 \
--bootstrap-server kafka-1:29092
컨슈머 테스트 결과입니다.
1
2
start.time, end.time, data.consumed.in.MB, MB.sec, data.consumed.in.nMsg, nMsg.sec, rebalance.time.ms, fetch.time.ms, fetch.MB.sec, fetch.nMsg.sec
2026-05-07 07:14:57:489, 2026-05-07 07:15:00:894, 98.1396, 28.8222, 100495, 29513.9501, 3190, 215, 456.4635, 467418.6047
약 3.4초 동안 98MB(약 10만 건)를 소비했고, 초당 약 3만 건 처리한 셈입니다.
참고 자료
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.