동물원을 탈출한 Kafka를 잡아왔습니다
https://downfa11.tistory.com/32
동물원을 탈출한 Kafka를 찾습니다
부제 : Kafka에서 이제 Zookeeper가 필요 없어졌다고...???네?????/Apache Kafka 2.8.0 출시 이후로 Zookeeper에 대한 의존성이 점차 제거되고 있다.다만 3.3.1 릴리즈부터 시작해서 4.0 부터 Zookeeper가 제
downfa11.tistory.com
이전 '동물원을 탈출한 Kafka를 찾습니다' 게시글에서 이어지는 글
왜 Apache Kafka일까?
- 높은 처리량
- 순차 접근 (Sequential I/O)
- 디스크에 연속적으로 데이터를 쓰고 읽는 방식
- write : 랜덤 접근하는 기존 방식과 다르게, Kafka는 디스크에 시간 순서대로(순차적) 데이터를 기록
- read : 데이터 읽을때도 디스크 헤더를 이동시킬 필요가 없음
- ZeroCopy
- sendfile() 시스템 콜을 통해 중간 복사 단계를 모두 생략해 속도 향상
- DMA(Direct Memory Access) : CPU가 직접 데이터 전송을 처리하지 않고 device가 메모리에 데이터를 쓰거나 읽도록 처리
- DMA와 ZeroCopy를 함께 사용해서 메모리에 복사하는 오버헤드와 CPU의 부담을 줄여서 더 높은 처리량과 성능을 달성
- 순차 접근 (Sequential I/O)
- 확장성
- Broker 수를 늘이거나 줄이는데 중단되지 않고 이뤄짐
- 영속성
- 데이터를 메모리가 아닌 디스크에 저장하기에 서비스가 종료되어도 영속성 유지
- 고가용성
- 일부 노드가 중지하더라도 안전하고 지속적인 데이터 처리가 가능
zookeeper-less-kafka
https://cwiki.apache.org/confluence/display/KAFKA/KIP-833%3A+Mark+KRaft+as+Production+Ready
KIP-833: Mark KRaft as Production Ready - Apache Kafka - Apache Software Foundation
Status Current state: Accepted Discussion thread: https://lists.apache.org/thread/90zkqvmmw3y8j6tkgbg3md78m7hs4yn6 JIRA: n/a Please keep the discussion on the mailing list rather than commenting on the wiki (wiki discussions get unwieldy fast). Proposed Ch
cwiki.apache.org
kafka 3.5 버전부터는 Zookeeper mode가 deprecated되며, 3.7 버전까지만 zk 모드로 지원해서 4.0 버전부터는 KRaft mode만 지원할 계획이라 한다.
기존 Kafka with zookeeper(zk mode)의 한계
kafka 자체가 아닌 외부 zookeeper에서 metadata를 관리하여서 확장성에 큰 제약을 준다.
- 데이터의 중복
- Broker와 Zookeeper의 metadata 불일치
- 시스템 복잡성 증가
무엇보다도.... zookeeper 관리에 따른 러닝 커브가 너무 심각했다.
Zookeeper와 KRaft 비교
그러나 새로 추가된 자체 시스템인 KRaft 모드를 통해 단순화시켜서 metadata의 일관성과 안정성을 보장한다.

- 확장성 : 적합한 수의 Broker로 크기가 조정되어서 처리량, 대기시간, 요구를 충족시키는 컴퓨팅을 통해 파티션을 확장
- 즉각적 장애 조치 : Kafka 내부에서 동작하여 metadata 장애 조치가 즉각적으로 이뤄짐
- 관리 용이성 : kafka를 쉽게 모니터링, 관리 및 지원
구조가 어떻게 변경되었는가?
KRaft 모드는 zookeeper와의 의존성을 제거하고, kafka 애플리케이션 내에서 metadata를 관리하는 Topic을 두는 독립적인 구조를 띈다.
기존 1개였던 Controller는 3개(권장사항)으로 늘어나고, 그중 하나의 Controller가 active Controller(=Leader) 역할을 담당하여 쓰기 작업을 맡는다.
리더 컨트롤러가 장애 또는 종료되는 경우, 내부의 합의 알고리즘으로 새로운 리더를 선출한다.
컨트롤러의 주요 역할이 파티션의 리더를 선출하는 것이기에, 이 선출 과정의 최적화가 KRaft의 주요 성능 개선 사항이다.
metadata를 관리하는 Raft 정족수(Quorum)으로 cluster의 변경사항을 포함해 zookeeper의 역할을 완전히 대신한다.
Kafka cluster가 지원하는 파티션 수는 노드당 혹은 전체 cluster의 파티션 수 제한을 통해서 지원하는 파티션 수가 달라진다.
Zookeeper를 사용하여 metadata를 관리하면 전체 cluster의 파티션 제한에서 주요 병목 현상이 발생했다고 한다. zookeeper의 파티션 상한은 200,000개로 이 병목의 원인은 metadata를 내부 leader 관리로 이동하는데 걸리는 시간이라 한다.

confluent의 실험 결과를 통해 Quorum에서의 파티션 종료 시간과 종료 후 복구하는 시간이 향상된 것을 볼 수 있다.
Controller Quorum 동작 방식
- Controller 노드는 Raft 합의 프로토콜을 사용하여 일관성과 Kafka의 리더 선택을 보장
- 활성 컨트롤러(metadata log의 leader)는 broker에서 생성된 모든 RPC를 처리
- follower 컨트롤러는 활성 컨트롤러에 기록된 데이터를 복제하고 활성 컨트롤러에 장애가 발생할 경우 상시 대기
- broker는 offset을 사용하여 KRaft Controller에 저장된 metadata를 추적해 효율적으로 전파, 장애 상황을 빠르게 복구
- 주기적으로 metadata를 disk에 기록하지만 disk에서 로그를 다시 읽지 않고, 메모리에서 읽어 빠르게 대응 가능
Kafka broker 구성하기
공식문서의 권장사항을 따라서, Docker-compose를 통해 KRaft 방식의 Kafka Broker를 3대 설정해보겠다.
networks:
kafka_network:
volumes:
kafka:
driver: local
services:
kafka:
image: bitnami/kafka:3.7.0
restart: always
container_name: kafka
ports:
- '9094:9094'
environment:
- KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE=true
# KRaft settings
- KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka:9093
- KAFKA_CFG_NODE_ID=0
- KAFKA_CFG_PROCESS_ROLES=controller,broker
# Listeners
- ALLOW_PLAINTEXT_LISTENER=yes
- KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093,EXTERNAL://:9094
- KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092,EXTERNAL://127.0.0.1:9094
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,EXTERNAL:PLAINTEXT,PLAINTEXT:PLAINTEXT
- KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
- KAFKA_CFG_INTER_BROKER_LISTENER_NAME=PLAINTEXT
networks:
- kafka_network
volumes:
- "kafka:/bitnami/kafka"
kafka-ui:
image: provectuslabs/kafka-ui
restart: always
container_name: kafka-ui
ports:
- '8080:8080'
environment:
- KAFKA_CLUSTERS_0_NAME=kafka-standAlone
- KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS=kafka:9092
- DYNAMIC_CONFIG_ENABLED=true
- KAFKA_CLUSTERS_0_AUDIT_TOPICAUDITENABLED=true
- KAFKA_CLUSTERS_0_AUDIT_CONSOLEAUDITENABLED=true
# - KAFKA_CLUSTERS_0_METRICS_PORT=9999
networks:
- kafka_network
결과

kafka-ui 환경에서 3개의 broker로 이뤄진 cluster 생성에 성공한 모습
출처 및 인용.
https://stackoverflow.com/questions/65682557/kafka-docker-image-that-works-without-zookeeper
https://docs.confluent.io/platform/current/installation/docker/config-reference.html
https://www.confluent.io/blog/what-is-kraft-and-how-do-you-use-it/
https://developer.confluent.io/learn/kraft/
https://www.confluent.io/ko-kr/blog/removing-zookeeper-dependency-in-kafka/