오랜만에 Kafka 를 볼 일 있어서 Docker Compose 환경으로 Kafka 3.5.1 를 설치하고 기본적인 환경을 테스트 해보고자 한다.
1. Kafka 클러스터 환경 둘러보기 Zookeeper 환경은 오래 되기도 했고 이미지를 새로 받아서 올려야 하는 관계로 KRaft 방식의 클러스터를 구성하기로 했다.
해당 방식의 차이는 브로커의 ID, 호스트, 포트 등의 정보, 토픽의 이름, 파티션 수, 리플리케이션 팩터와 같은 '메타 데이터'를 어디서 관리 하느냐의 차이인데, KRaft 의 경우 2.8 이후에 도입이 되었고 내장되어 있는 메타 데이터 관리 컨트롤러인 '쿼럼 컨트롤러'와 연동하여 더 나은 성능을 내는 것으로 알려져 있다.
GitHub - ArminShoeibi/KafkaDockerCompose: Kafka 3.5.1 (KRaft) + Kafka UI DockerCompose
Kafka 3.5.1 (KRaft) + Kafka UI DockerCompose. Contribute to ArminShoeibi/KafkaDockerCompose development by creating an account on GitHub.
TaskVibes: ADHD Daily Planner - Apps on Google Play
adhd, alarm, daily, planner, geofence
1) docker-compose 중 주요 부분 Kafka00Service:
image: bitnami/kafka:3.5.1-debian-11-r44
restart: unless-stopped
container_name: Kafka00Container
ports:
- '10000:9094'
environment:
- KAFKA_CFG_BROKER_ID=0
- KAFKA_CFG_NODE_ID=0
# KRAFT_CLUSTER_ID 설정으로 모든 브로커가 동일한 ID를 가진다
- KAFKA_KRAFT_CLUSTER_ID=HsDBs9l6UUmQq7Y5E6bNlw
- KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@Kafka00Service:9093,1@Kafka01Service:9093,2@Kafka02Service:9093
- ALLOW_PLAINTEXT_LISTENER=yes
- KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE=true
# 브로커가 내부적으로 통신하는 주소
- KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093,EXTERNAL://:9094
# 프로듀스나 컨슈머에 제공할 주소, 로컬 PC에서 접근할 때 127.0.0.1:10000 를 이용한다
- KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://Kafka00Service:9092,EXTERNAL://127.0.0.1:10000
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,EXTERNAL:PLAINTEXT,PLAINTEXT:PLAINTEXT
- KAFKA_CFG_OFFSETS_TOPIC_REPLICATION_FACTOR=3
- KAFKA_CFG_TRANSACTION_STATE_LOG_REPLICATION_FACTOR=3
- KAFKA_CFG_TRANSACTION_STATE_LOG_MIN_ISR=2
- KAFKA_CFG_PROCESS_ROLES=controller,broker
- KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
networks:
- kafka_network
volumes:
- "Kafka00:/bitnami/kafka"
Broker 설정
KafkaWebUiService:
image: provectuslabs/kafka-ui:latest
restart: always
container_name: KafkaWebUiContainer
ports:
- '8080:8080'
environment:
- KAFKA_CLUSTERS_0_NAME=Local-Kraft-Cluster
- KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS=Kafka00Service:9092,Kafka01Service:9092,Kafka02Service:9092
- DYNAMIC_CONFIG_ENABLED=true
- KAFKA_CLUSTERS_0_AUDIT_TOPICAUDITENABLED=true
- KAFKA_CLUSTERS_0_AUDIT_CONSOLEAUDITENABLED=true
#- KAFKA_CLUSTERS_0_METRICS_PORT=9999
depends_on:
- Kafka00Service
- Kafka01Service
- Kafka02Service
networks:
- kafka_network
Kafka UI 관리자 (localhost:8080)
TaskVibes: ADHD Daily Planner - Apps on Google Play
adhd, alarm, daily, planner, geofence
2) 전체 docker-compose.yaml networks:
kafka_network:
volumes:
Kafka00:
driver: local
Kafka01:
driver: local
Kafka02:
driver: local
services:
##Kafka 00
Kafka00Service:
image: bitnami/kafka:3.5.1-debian-11-r44
restart: unless-stopped
container_name: Kafka00Container
ports:
- '10000:9094'
environment:
- KAFKA_CFG_BROKER_ID=0
- KAFKA_CFG_NODE_ID=0
- KAFKA_KRAFT_CLUSTER_ID=HsDBs9l6UUmQq7Y5E6bNlw
- KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@Kafka00Service:9093,1@Kafka01Service:9093,2@Kafka02Service:9093
- ALLOW_PLAINTEXT_LISTENER=yes
- KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE=true
- KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093,EXTERNAL://:9094
- KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://Kafka00Service:9092,EXTERNAL://127.0.0.1:10000
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,EXTERNAL:PLAINTEXT,PLAINTEXT:PLAINTEXT
- KAFKA_CFG_OFFSETS_TOPIC_REPLICATION_FACTOR=3
- KAFKA_CFG_TRANSACTION_STATE_LOG_REPLICATION_FACTOR=3
- KAFKA_CFG_TRANSACTION_STATE_LOG_MIN_ISR=2
- KAFKA_CFG_PROCESS_ROLES=controller,broker
- KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
networks:
- kafka_network
volumes:
- "Kafka00:/bitnami/kafka"
##Kafka 01
Kafka01Service:
image: bitnami/kafka:3.5.1-debian-11-r44
restart: always
container_name: Kafka01Container
ports:
- '10001:9094'
environment:
- KAFKA_CFG_BROKER_ID=1
- KAFKA_CFG_NODE_ID=1
- KAFKA_KRAFT_CLUSTER_ID=HsDBs9l6UUmQq7Y5E6bNlw
- KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@Kafka00Service:9093,1@Kafka01Service:9093,2@Kafka02Service:9093
- ALLOW_PLAINTEXT_LISTENER=yes
- KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE=true
- KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093,EXTERNAL://:9094
- KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://Kafka01Service:9092,EXTERNAL://127.0.0.1:10001
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,EXTERNAL:PLAINTEXT,PLAINTEXT:PLAINTEXT
- KAFKA_CFG_OFFSETS_TOPIC_REPLICATION_FACTOR=3
- KAFKA_CFG_TRANSACTION_STATE_LOG_REPLICATION_FACTOR=3
- KAFKA_CFG_TRANSACTION_STATE_LOG_MIN_ISR=2
- KAFKA_CFG_PROCESS_ROLES=controller,broker
- KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
networks:
- kafka_network
volumes:
- "Kafka01:/bitnami/kafka"
##Kafka 02
Kafka02Service:
image: bitnami/kafka:3.5.1-debian-11-r44
restart: always
container_name: Kafka02Container
ports:
- '10002:9094'
environment:
- KAFKA_CFG_BROKER_ID=2
- KAFKA_CFG_NODE_ID=2
- KAFKA_KRAFT_CLUSTER_ID=HsDBs9l6UUmQq7Y5E6bNlw
- KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@Kafka00Service:9093,1@Kafka01Service:9093,2@Kafka02Service:9093
- ALLOW_PLAINTEXT_LISTENER=yes
- KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE=true
- KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093,EXTERNAL://:9094
- KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://Kafka02Service:9092,EXTERNAL://127.0.0.1:10002
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,EXTERNAL:PLAINTEXT,PLAINTEXT:PLAINTEXT
- KAFKA_CFG_OFFSETS_TOPIC_REPLICATION_FACTOR=3
- KAFKA_CFG_TRANSACTION_STATE_LOG_REPLICATION_FACTOR=3
- KAFKA_CFG_TRANSACTION_STATE_LOG_MIN_ISR=2
- KAFKA_CFG_PROCESS_ROLES=controller,broker
- KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
networks:
- kafka_network
volumes:
- "Kafka02:/bitnami/kafka"
KafkaWebUiService:
image: provectuslabs/kafka-ui:latest
restart: always
container_name: KafkaWebUiContainer
ports:
- '8080:8080'
environment:
- KAFKA_CLUSTERS_0_NAME=Local-Kraft-Cluster
- KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS=Kafka00Service:9092,Kafka01Service:9092,Kafka02Service:9092
- DYNAMIC_CONFIG_ENABLED=true
- KAFKA_CLUSTERS_0_AUDIT_TOPICAUDITENABLED=true
- KAFKA_CLUSTERS_0_AUDIT_CONSOLEAUDITENABLED=true
#- KAFKA_CLUSTERS_0_METRICS_PORT=9999
depends_on:
- Kafka00Service
- Kafka01Service
- Kafka02Service
networks:
- kafka_network
docker-compose.yaml
3) docker-compose 실행명령 docker-compose -f docker-compose.yaml up
TaskVibes: ADHD Daily Planner - Apps on Google Play
adhd, alarm, daily, planner, geofence
2. Kafka 기본 기능 테스트 도커로 생성한 카프카 브로커 컨테이너에 접근해서 kafka 명령을 사용하기 위해 아래와 같이 실행한다.
docker-compose exec -it Kafka01Service /bin/bash
해당 컨테이너에 kafka는 /opt/bitnami/kafka 에 위치하고 있다.
1) Topic 생성 tester 라는 이름의 topic 을 각 브로커에 생성하도록 요청했고 파티션 수와 리플리케이션 팩터를 같이 설정하였다.
여기서 파티션 수는 설정시에 프로듀서 수와 컨슈머 수에 맞춰서 설정하는 것이 좋다. 너무 적으면 병목이 발생하고 많으면 오버헤드가 발생한다.
리플리케이션 팩터는 하나의 브로커가 종료 되더라도 안정성을 유지할 수 있도록 데이터가 중요하다면 높게 설정하고 중요한 데이터가 아니라면 낮게도 설정 가능하겠다.
./kafka-topics.sh --create --topic tester --bootstrap-server Kafka00Service:9092,Kafka01Service:9092,Kafka02Service:9092 --partitions 3 --replication-factor 2
2) Console Producer, Consumer 테스트 ./kafka-console-producer.sh --topic tester --bootstrap-server Kafka00Service:9092,Kafka01Service:9092,Kafka02Service:9092
위 명령어로 'one' 이라는 메시지 하나를 넣었고 Kafka UI 에서 확인했고 consumer 도 정상 동작 하는 것을 확인했다.
./kafka-console-consumer.sh --topic tester --from-beginning --bootstrap-server Kafka00Service:9092,Kafka01Service:9092,Kafka02Service:9092
TaskVibes: ADHD Daily Planner - Apps on Google Play
adhd, alarm, daily, planner, geofence