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.3 | 2026년 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 구조: 컨트롤러 쿼럼과 메타데이터 토픽
핵심 개념 세 가지:
- 컨트롤러 쿼럼: 3개 또는 5개 노드로 구성된 Raft 그룹이 메타데이터 변경을 합의한다. 컨트롤러는 브로커와 동일한 JVM 프로세스에서 실행하거나(결합 모드), 별도 프로세스로 분리할 수 있다(격리 모드). 프로덕션 대규모 배포에서는 격리 모드가 권장된다.
__cluster_metadata토픽: 토픽 설정, 파티션 배정, ISR(In-Sync Replica), 브로커 등록 정보 등 모든 메타데이터가 이 단일 파티션 토픽에 기록된다. Raft 로그이자 Kafka 토픽이므로 일반 토픽 모니터링 도구로 관찰할 수 있다.
- 메타데이터 구독: 브로커는 컨트롤러에서 메타데이터 변경 이벤트를 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 versionZooKeeper 앙상블 상태 정상 확인 (마이그레이션 전 기준)
▼
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 앙상블 종료 (데이터 백업 후)
운영 관찰 포인트
컨트롤러 쿼럼 건강도
# 쿼럼 리더/팔로워 상태 확인
kafka-metadata-quorum.sh --bootstrap-server broker:9092 --describe --status
# 메타데이터 복제 오프셋 lag 확인
kafka-metadata-quorum.sh --bootstrap-server broker:9092 --describe --replicationLastCaughtUpTimestamp 값이 컨트롤러 리더와 크게 차이 나는 팔로워가 있으면 네트워크/디스크 문제를 의심한다.
메타데이터 스냅샷
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은 하위 호환성 일부를 제거했다. 마이그레이션 전 반드시 확인해야 할 항목:
- 클라이언트 API 버전: Kafka 4.0은 Kafka 0.x~2.x 시대의 구형 프로토콜(API 버전 0~2)을 제거했다. 레거시 클라이언트가 있으면 업그레이드 후 연결 실패한다.
- MirrorMaker 1.x 제거: MirrorMaker 2(Kafka Connect 기반)로 전환 필요.
kafka.logs.dir설정 제거:log.dirs로 통일.- Scala 제거 API: Scala로 작성된 일부 Admin 스크립트가 Java 구현으로 대체됐다. 내부 스크립트 경로 확인 필요.
롤백 가능성
KRaft 마이그레이션 완료 후 ZooKeeper 모드로 롤백하는 공식 경로는 없다. 마이그레이션 전 반드시:
- 전체 클러스터 데이터 백업(KV 스냅샷 또는 MirrorMaker로 별도 클러스터 미러링 유지)
- 마이그레이션은 스테이징 환경에서 전체 사이클 먼저 검증
migration.state = MIGRATION단계까지는 ZK 앙상블을 살려 두므로 이 단계에서 문제 발생 시 브로커를 이전 설정으로 롤링 복구 가능
요점 정리
- KRaft = Kafka 자체 Raft 구현으로 ZooKeeper 의존성을 완전히 제거했다. 컨트롤러 쿼럼이 메타데이터를 관리하고 브로커는 메타데이터를 구독한다.
- Kafka 4.0부터 ZooKeeper 코드가 삭제됐으므로 3.x에서 KRaft 마이그레이션을 완료하지 않으면 4.x로 업그레이드할 수 없다.
- Kafka 4.3은 KRaft 성숙 릴리스로, 대규모 파티션 환경의 메타데이터 재로드 성능과 운영 가시성이 개선됐다.
- 마이그레이션은 브리지 모드(ZK + KRaft 동시 운영) → KRaft 전용 순서로 단계적으로 진행하며, 각 단계마다
kafka-metadata-quorum.sh로 상태를 검증한다. - 레거시 클라이언트 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/