Kafka 기초 (2) - Installation and First Run
Docker로 Kafka broker를 띄우고 topic을 만들어 console producer와 consumer로 첫 이벤트를 주고받습니다. bootstrap-server의 의미와 --from-beginning 함정까지 다룹니다.
Kafka 기초 시리즈의 2편입니다. 전체 목차는 0편에 있습니다.
Installation
로컬 실습은 공식 Docker image가 가장 간단합니다.
1
docker run -d --name kafka -p 9092:9092 apache/kafka:4.0.0
-d, -p, --name 옵션이 낯설면 Docker 기초 4편에 정리되어 있습니다. 제대로 떴는지는 로그로 확인합니다.
1
2
docker logs kafka
# ... Kafka Server started ...
Kafka Server started가 보이면 broker 하나가 9092 포트에서 요청을 기다리는 상태입니다.
검색하면 나오는 예전 자료의 ZooKeeper 구성은 필요 없습니다. Kafka는 오랫동안 메타데이터 관리를 ZooKeeper라는 별도 프로그램에 맡겼는데, 4.0부터 완전히 제거하고 내장된 KRaft mode가 그 역할을 맡습니다. ZooKeeper가 등장하는 자료는 그 시절 것이므로 지금 따라 할 필요가 없습니다.
시리즈 내내 이 container를 계속 씁니다. 실습을 전부 마치고 지울 때는 docker rm -f kafka입니다.
Topic 생성
이벤트를 주고받으려면 먼저 분류 단위인 topic이 있어야 합니다. Kafka의 관리 도구들은 broker 안에 셸 스크립트로 들어 있어서, docker exec로 container 안의 스크립트를 실행하는 방식으로 씁니다.
1
2
3
docker exec kafka /opt/kafka/bin/kafka-topics.sh \
--bootstrap-server localhost:9092 --create --topic events --partitions 3
# Created topic events.
1
2
docker exec kafka /opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --create --topic events --partitions 3
① ② ③ ④
- ①
docker exec kafka: kafka container 안에서 명령을 실행합니다 - ②
kafka-topics.sh: topic을 만들고 조회하고 지우는 관리 도구입니다 - ③
--bootstrap-server localhost:9092: 접속할 broker의 주소입니다. Kafka의 모든 client 도구가 이 옵션을 받습니다. bootstrap이라는 이름은 “첫 접속용”이라는 뜻으로, client는 이 주소로 처음 접속해 cluster의 전체 broker 목록을 받아온 뒤 실제 통신을 시작합니다. 지금은 broker가 하나라 그 주소가 전부입니다 - ④
--create --topic events --partitions 3: events라는 이름의 topic을 partition 3개로 만듭니다
First Run
1편의 producer와 consumer를 코드 없이 체험하는 console 도구가 있습니다. 터미널 두 개를 엽니다.
1
2
3
# 터미널 1: producer. 입력하는 줄 하나가 이벤트 하나가 된다
docker exec -it kafka /opt/kafka/bin/kafka-console-producer.sh \
--bootstrap-server localhost:9092 --topic events
1
2
3
# 터미널 2: consumer. --from-beginning으로 처음부터 읽는다
docker exec -it kafka /opt/kafka/bin/kafka-console-consumer.sh \
--bootstrap-server localhost:9092 --topic events --from-beginning
producer 터미널에 아무 줄이나 입력하면 consumer 터미널에 그대로 나타납니다.
1
2
3
# 터미널 1 (producer) # 터미널 2 (consumer)
>hello kafka hello kafka
>두 번째 이벤트 두 번째 이벤트
입력한 줄이 반대편에 나타나면 producer → broker → consumer의 전체 경로가 확인된 것입니다. docker run의 -it가 붙는 이유는 두 도구 모두 터미널 입력을 계속 받는 대화형 프로그램이기 때문이고, 종료는 Ctrl+C입니다.
방금 무슨 일이 있었나
세 줄로 정리하면 이렇습니다.
- producer가 입력받은 줄을 이벤트로 만들어 broker의 events topic에 보냈습니다
- broker는 이벤트를 partition 세 개 중 하나의 끝에 추가하고 offset 번호를 붙여 디스크에 저장했습니다
- consumer는 events topic을 구독하고 있다가 새 이벤트를 받아 출력했습니다
여기서 확인할 것이 하나 있습니다. consumer를 Ctrl+C로 끄고, producer에서 몇 줄을 더 보낸 뒤, consumer를 다시 켜 봅니다. 꺼져 있는 동안 보낸 이벤트까지 전부 나타납니다. 읽는 쪽이 없어도 이벤트는 broker의 log에 쌓여 있다는 1편의 성질이 바로 이것입니다.
–from-beginning 함정
첫 실습에서 가장 흔하게 밟는 함정이 있습니다. producer로 먼저 보내 놓고 consumer를 나중에 켰는데 아무것도 안 나오는 경우입니다.
console consumer의 기본 동작이 “접속한 시점 이후의 새 이벤트부터 읽기”라서, 접속 이전의 이벤트를 건너뛴 것입니다. 과거 이벤트까지 보려면 위 예제처럼 --from-beginning을 붙여 offset 0부터 읽게 해야 합니다. 이벤트가 사라진 것이 아니라 읽기 시작 위치의 문제라는 것을 알아두면, 나중에 애플리케이션 client의 auto.offset.reset 설정(5편)도 같은 원리로 이해됩니다.
자주 쓰는 확인 명령
| 명령 | 역할 |
|---|---|
kafka-topics.sh --list | topic 목록 |
kafka-topics.sh --describe --topic events | topic의 partition 구성 상세 (3편에서 뜯어봅니다) |
kafka-console-consumer.sh --from-beginning | 과거 이벤트 포함 전체 읽기 |
docker logs kafka | broker 로그. 접속 문제가 생기면 첫 번째 확인 창구 |
다음 편에서 events topic의 partition 3개가 실제로 어떻게 쓰이는지, key로 순서를 보장하는 방법과 함께 확인합니다.