LLM WikiAccess-protected knowledge portal
← 스터디 홈
157편 · 약 15분

Apache Kafka KRaft: ZooKeeper 없는 클러스터 운영과 Kafka 4.x 마이그레이션 실전 체크리스트

요약

항목내용
KRaft란Raft 합의 프로토콜 기반 Kafka 자체 메타데이터 관리 (ZooKeeper 대체)
GA 시점Kafka 3.3 (2022년 9월) KRaft GA, Kafka 4.0 (2024년 10월) ZooKeeper 지원 제거
Kafka 4.32026년 5월 릴리스, KRaft 성숙화 — 마이그레이션 완료 기한의 실질적 마지막 검증 기회
핵심 구조 변화ZooKeeper 대신 __cluster_metadata 내부 토픽에 메타데이터 저장, 컨트롤러 쿼럼 구성
운영 이점클러스터 시작 시간 단축, 파티션 리더 선출 속도 향상, 외부 의존성 제거
마이그레이션 방법kafka-storage.sh, kafka-features.sh 활용 롤링 마이그레이션 또는 신규 클러스터 이전

ZooKeeper 의존성이 왜 문제였나

Kafka는 창기부터 클러스터 메타데이터(브로커 등록, 토픽 설정, 파티션 배정, 컨트롤러 선출)를 Apache ZooKeeper에 저장했다. 이 설계는 단순했지만 운영 복잡도를 두 배로 만들었다.

  • 두 시스템 운영: Kafka 클러스터와 ZooKeeper 앙상블을 별도로 모니터링·패치·백업해야 했다.
  • 컨트롤러 재선출 지연: 액티브 컨트롤러가 죽으면 ZooKeeper 세션 타임아웃(기본 30초) 이후에야 새 컨트롤러가 선출됐다. 이 기간에 파티션 리더 선출이 차단된다.
  • 파티션 수 제한: ZooKeeper 쿼리 오버헤드로 파티션 10만 개가 실질적 상한선이었다. 더 많은 파티션을 갖는 대규모 클러스터는 컨트롤러 재시작 시 수십 분이 걸렸다.
  • 메타데이터 확장성: 토픽·파티션이 늘어날수록 ZooKeeper znode 수가 증가해 성능이 저하됐다.

KIP-500(2019년)은 이 구조적 문제를 해결하는 방향을 제시했다.


KRaft 구조: 컨트롤러 쿼럼과 메타데이터 토픽

컨트롤러 쿼럼 (Raft) 액티브 컨트롤러 리더 (1개) 스탠바이 컨트롤러 팔로워 (2개 이상) Raft __cluster_metadata 내부 토픽 (단일 파티션, RF=쿼럼 크기) 브로커 노드 브로커 1 브로커 2 브로커 3 메타데이터 팔로워 컨트롤러에서 메타데이터 구독 메타데이터 Push 프로듀서 / 컨슈머 / Admin API 부트스트랩 → 브로커 직접 통신 (ZooKeeper 주소 설정 불필요) Admin 작업도 브로커 API로 처리
KRaft 클러스터 아키텍처

핵심 개념 세 가지:

  1. 컨트롤러 쿼럼: 3개 또는 5개 노드로 구성된 Raft 그룹이 메타데이터 변경을 합의한다. 컨트롤러는 브로커와 동일한 JVM 프로세스에서 실행하거나(결합 모드), 별도 프로세스로 분리할 수 있다(격리 모드). 프로덕션 대규모 배포에서는 격리 모드가 권장된다.
  1. __cluster_metadata 토픽: 토픽 설정, 파티션 배정, ISR(In-Sync Replica), 브로커 등록 정보 등 모든 메타데이터가 이 단일 파티션 토픽에 기록된다. Raft 로그이자 Kafka 토픽이므로 일반 토픽 모니터링 도구로 관찰할 수 있다.
  1. 메타데이터 구독: 브로커는 컨트롤러에서 메타데이터 변경 이벤트를 Push 방식으로 수신한다. ZooKeeper 워치(watch) 폴링 방식보다 지연이 낮고 일관성이 높다.

Kafka 4.x와 ZooKeeper 완전 제거

Kafka 3.x 타임라인:

  • 3.3 (2022-09): KRaft GA. 프로덕션 사용 권장.
  • 3.5 (2023-06): ZooKeeper 모드 지원 Deprecated 선언.
  • 3.7 (2024-03): ZooKeeper 모드에서 새 기능 비활성화 시작.
  • 4.0 (2024-10): ZooKeeper 모드 코드 완전 제거. KRaft 전용.

Kafka 4.3 (2026년 5월):

Kafka 4.x 계열의 세 번째 마이너 릴리스로, KRaft 성숙화에 집중했다. 주요 변경사항:

  • 컨트롤러 재선출 시 브로커 영향 최소화(리더 재선출 배치 처리 개선)
  • kafka-metadata-quorum.sh 명령 출력 개선(쿼럼 상태, 오프셋 lag 확인 편의성 향상)
  • 대규모 파티션(100만+) 환경에서 메타데이터 스냅샷 재로드 성능 향상
  • 버전 4.3은 Kafka 4.0~4.2에서 이미 KRaft로 운영 중인 클러스터에 대한 인플레이스 업그레이드 지원

주의: Kafka 4.0부터는 ZooKeeper 모드 클러스터를 직접 업그레이드할 수 없다. 3.x KRaft로 먼저 마이그레이션 후 4.x로 업그레이드해야 한다.


마이그레이션 경로

전제 조건 확인
Kafka 3.5~3.8로 업그레이드 완료 (4.x 직접 ZK 마이그레이션 불가)
Java 17+ 확인 (Kafka 4.x 요구사항)
kafka-storage.sh 버전 확인: kafka-storage.sh version
ZooKeeper 앙상블 상태 정상 확인 (마이그레이션 전 기준)
KRaft 컨트롤러 쿼럼 준비
새 컨트롤러 노드 3개 구성 (또는 기존 브로커에 결합 모드 설정)
각 노드: process.roles=controller, node.id=<고유 ID>, controller.quorum.voters 설정
kafka-storage.sh format -t $(kafka-storage.sh random-uuid) -c server.properties
컨트롤러 쿼럼 선거 완료 확인: kafka-metadata-quorum.sh --describe --status
브리지 모드로 브로커 롤링 재시작
브로커에 controller.quorum.voters 추가, ZK 설정 유지 (동시 접속)
브로커 하나씩 재시작 → ISR 복구 확인 후 다음 브로커
확인 명령: kafka-features.sh --describe (migration.state 값 확인)
migration.state = MIGRATION (진행 중) → KRAFT_CONTROLLER (완료)
ZooKeeper 완전 분리 및 검증
모든 브로커에서 ZK 설정 제거 후 최종 롤링 재시작
kafka-metadata-quorum.sh --describe --replication으로 쿼럼 상태 확인
ZooKeeper 앙상블 중단 전 48시간 모니터링 (메타데이터 토픽 LAG 확인)
ZK 앙상블 종료 (데이터 백업 후)
ZooKeeper → KRaft 마이그레이션 체크리스트

운영 관찰 포인트

컨트롤러 쿼럼 건강도

# 쿼럼 리더/팔로워 상태 확인
kafka-metadata-quorum.sh --bootstrap-server broker:9092 --describe --status

# 메타데이터 복제 오프셋 lag 확인
kafka-metadata-quorum.sh --bootstrap-server broker:9092 --describe --replication

LastCaughtUpTimestamp 값이 컨트롤러 리더와 크게 차이 나는 팔로워가 있으면 네트워크/디스크 문제를 의심한다.

메타데이터 스냅샷

KRaft는 __cluster_metadata 로그가 무한히 커지지 않도록 주기적으로 스냅샷을 생성한다. 스냅샷 생성 주기는 metadata.log.max.record.bytes.between.snapshots (기본 20MB)로 제어한다. 재시작 시 마지막 스냅샷 이후 로그만 재생하므로 시작 시간이 ZK 모드 대비 대폭 단축된다.

실제 이득 수치 (Confluent 발표 기준):

환경ZK 모드 컨트롤러 재시작KRaft 컨트롤러 재시작
파티션 10만 개~45초~3초
파티션 100만 개~20분~10초

알림 설정 권장

  • kafka.controller:type=KafkaController,name=ActiveControllerCount → 0이면 즉시 경보
  • kafka.controller:type=KafkaController,name=GlobalPartitionCount → 급격한 감소 알림
  • 컨트롤러 쿼럼 팔로워 LAG → 기준값(예: 5초) 초과 시 경보

Kafka 4.x 업그레이드 시 추가 주의사항

Kafka 4.0은 하위 호환성 일부를 제거했다. 마이그레이션 전 반드시 확인해야 할 항목:

  1. 클라이언트 API 버전: Kafka 4.0은 Kafka 0.x~2.x 시대의 구형 프로토콜(API 버전 0~2)을 제거했다. 레거시 클라이언트가 있으면 업그레이드 후 연결 실패한다.
  2. MirrorMaker 1.x 제거: MirrorMaker 2(Kafka Connect 기반)로 전환 필요.
  3. kafka.logs.dir 설정 제거: log.dirs로 통일.
  4. Scala 제거 API: Scala로 작성된 일부 Admin 스크립트가 Java 구현으로 대체됐다. 내부 스크립트 경로 확인 필요.

롤백 가능성

KRaft 마이그레이션 완료 후 ZooKeeper 모드로 롤백하는 공식 경로는 없다. 마이그레이션 전 반드시:

  • 전체 클러스터 데이터 백업(KV 스냅샷 또는 MirrorMaker로 별도 클러스터 미러링 유지)
  • 마이그레이션은 스테이징 환경에서 전체 사이클 먼저 검증
  • migration.state = MIGRATION 단계까지는 ZK 앙상블을 살려 두므로 이 단계에서 문제 발생 시 브로커를 이전 설정으로 롤링 복구 가능

요점 정리

  1. KRaft = Kafka 자체 Raft 구현으로 ZooKeeper 의존성을 완전히 제거했다. 컨트롤러 쿼럼이 메타데이터를 관리하고 브로커는 메타데이터를 구독한다.
  2. Kafka 4.0부터 ZooKeeper 코드가 삭제됐으므로 3.x에서 KRaft 마이그레이션을 완료하지 않으면 4.x로 업그레이드할 수 없다.
  3. Kafka 4.3은 KRaft 성숙 릴리스로, 대규모 파티션 환경의 메타데이터 재로드 성능과 운영 가시성이 개선됐다.
  4. 마이그레이션은 브리지 모드(ZK + KRaft 동시 운영) → KRaft 전용 순서로 단계적으로 진행하며, 각 단계마다 kafka-metadata-quorum.sh로 상태를 검증한다.
  5. 레거시 클라이언트 API 버전과 MirrorMaker 1.x 제거가 4.x 업그레이드 시 주요 호환성 함정이다.

References

  • Apache Kafka Documentation — KRaft Migration Guide. https://kafka.apache.org/documentation/#kraft_migration
  • KIP-500: Replace ZooKeeper with a Self-Managed Metadata Quorum. https://cwiki.apache.org/confluence/display/KAFKA/KIP-500
  • KIP-833: Mark KRaft as Production Ready. https://cwiki.apache.org/confluence/display/KAFKA/KIP-833
  • Apache Kafka 4.0 Release Notes. https://kafka.apache.org/blog/apache-kafka-4-0-release-announcement
  • Apache Kafka 4.3 Release Notes. https://kafka.apache.org/blog/apache-kafka-4-3-release-announcement
  • Confluent Blog, "Kafka Without ZooKeeper: A Sneak Peek At the Simplest Kafka Yet." https://www.confluent.io/blog/kafka-without-zookeeper-a-sneak-peek
  • Jakub Scholz, "Kafka KRaft: From Beta to GA," Strimzi Blog, 2022. https://strimzi.io/blog/2022/09/07/kafka-kraft/