Kafka 4.0.0 핵심 변경사항 — ZooKeeper 완전 제거와 API 정리
Apache Kafka Official Documentation — Getting Started (v4.3) — Apache Software Foundation Section 5: Upgrading — 'Notable changes in 4.0.0' (pp.26-33)
이 모듈을 다 읽으면
- Kafka 4.0에서 ZooKeeper가 완전히 제거된 배경과 그로 인한 실무 영향을 설명할 수 있다.
- Java/Scala 버전 요구사항 변화와 Consumer API의 poll(long)→poll(Duration) 전환이 기존 코드에 미치는 영향을 판단할 수 있다.
- CLI 옵션(--zookeeper, --broker-list, --whitelist 등)이 어떻게 대체되었는지 설명할 수 있다.
- 2017년 출간된 Kafka Definitive Guide(ZooKeeper 시대) 서술과 현재 4.x 기준의 차이를 구분할 수 있다.
Kafka 4.0.0은 ZooKeeper 완전 제거, Java/Scala 최소 버전 상향, Consumer/Producer API 정리, 다수의 레거시 CLI 옵션 제거를 한 번에 단행한 메이저 릴리스다. 2017년 Definitive Guide가 서술하는 ZooKeeper 필수 아키텍처는 이제 3.x 이하에만 해당한다.
ZooKeeper 완전 제거
Kafka 4.0의 가장 큰 변화는 ZooKeeper 모드가 코드베이스에서 완전히 제거되고 KRaft 모드만 남았다는 점이다. KRaft 관련 기본 설정 파일도 더 이상 별도의 config/kraft 디렉터리에 있지 않고 다른 설정 파일들과 함께 config 디렉터리로 통합되었다. kafka-acls 같은 명령행 도구에서도 --authorizer, --authorizer-properties, --zk-tls-config-file 옵션이 제거되어 --bootstrap-server 또는 --bootstrap-controller로 대체됐고, AdminClient 계열 명령의 --zookeeper 옵션도 전부 제거되어 --bootstrap-server만 사용할 수 있다. kafka.admin.ZkSecurityMigrator 도구 자체도 사라졌다.
여기서 짚어둘 시대차가 있다. 2017년에 나온 Kafka Definitive Guide는 ZooKeeper가 브로커 메타데이터 관리와 컨트롤러 선출에 필수였던 시절의 책이다. 그 책의 'ZooKeeper 앙상블', '컨트롤러 선출' 관련 설명은 3.x 이하 ZooKeeper 모드 기준이며, 4.x부터는 해당 역할을 전부 KRaft 컨트롤러 쿼럼이 대체한다는 점을 함께 기억해야 한다.
핵심 포인트
- Kafka 4.0부터 ZooKeeper 모드가 코드베이스에서 완전히 제거되고 KRaft 모드만 지원된다.
- --zookeeper, --authorizer, --zk-tls-config-file 등 ZK 관련 CLI 옵션이 전부 제거되고 --bootstrap-server/--bootstrap-controller로 대체됐다.
- 2017년 Definitive Guide의 ZooKeeper 관련 설명은 3.x 이하 기준이며 4.x에는 적용되지 않는다.
Java/Scala 버전 요구사항 상향
클라이언트와 Kafka Streams 애플리케이션에 필요한 최소 Java 버전이 Java 8에서 Java 11로 올라갔고, 브로커·Connect·명령행 도구는 이제 Java 17을 요구한다. 동시에 Java 23 지원이 새로 추가됐다. Scala 2.12 지원도 4.0에서 제거됐다(Scala 2.13만 지원). 로깅 프레임워크도 Log4j에서 Log4j2로 전면 이관되었으며, 기존 Log4j 설정 파일은 log4j-transform-cli 도구로 변환하거나 Log4j1-to-2 브리지로 제한적 호환을 가져갈 수 있다. KafkaLog4jAppender는 제거되어 Log4j2 appender로 이전해야 한다.
핵심 포인트
- 클라이언트·Kafka Streams: Java 8 → Java 11 최소 요구, 브로커·Connect·도구: Java 17 최소 요구. Java 23도 지원.
- Scala 2.12 지원이 4.0에서 제거되어 Scala 2.13만 지원한다.
- 로깅이 Log4j에서 Log4j2로 이관되었고 KafkaLog4jAppender는 제거됐다.
Consumer/Producer/CLI API 변경
Consumer의 poll(long) 메서드가 제거되고 poll(Duration)만 남았다. 두 메서드는 동작이 다른데, poll(Duration)은 파티션 할당을 기다리는 동안 timeout을 넘어서도 블록하지 않는 반면, 예전 poll(long)은 timeout을 넘겨서도 대기했다. 코드를 poll(long)에서 poll(Duration)으로 그대로 치환만 하면 이 미묘한 타이밍 차이 때문에 예상과 다르게 동작할 수 있다.
Producer 쪽에서는 linger.ms 기본값이 0에서 5로 변경됐다 — 배치를 조금 더 크게 모으는 쪽이 지연을 늘리는 것보다 오히려 처리량/지연 총합 면에서 유리하다는 판단에서다. enable.idempotence 설정도 더 이상 max.in.flight.requests.per.connection이 5를 넘을 때 자동으로 false로 폴백하지 않는다.
명령행 도구들도 대거 정리됐다: kafka-console-consumer의 --whitelist는 --include로, kafka-verifiable-consumer/kafka-replica-verification의 --broker-list 계열 옵션은 --bootstrap-server(또는 --topics-include)로, kafka-console-producer의 --max-partition-memory-bytes는 --batch-size로 대체(4.2에서 deprecated, 5.0 제거 예정)됐다. kafka-configs.sh는 이제 deprecated된 alterConfigs API 대신 incrementalAlterConfigs API를 사용한다.
핵심 포인트
- Consumer.poll(long)이 제거되고 poll(Duration)만 남았다 — timeout 초과 시 블로킹 동작이 달라진다는 점에 주의해야 한다.
- Producer의 linger.ms 기본값이 0에서 5로 바뀌었다.
- --whitelist→--include, --broker-list→--bootstrap-server 등 레거시 CLI 옵션이 대거 정리됐다.
그 외 주요 변경: MirrorMaker, 트랜잭션, 프로토콜 하한
오리지널 MirrorMaker(MM1)와 관련 클래스가 완전히 제거되어 Connect 기반 MirrorMaker 2(MM2)만 남았다. 트랜잭션 프로토콜은 KIP-890(Transactions Server-Side Defense)으로 강화되어, 4.0 프로듀서 클라이언트는 트랜잭션마다 producer epoch를 증가시켜 의도치 않은 메시지가 다음 트랜잭션에 끼어드는 것을 막는다. 오래된 프로토콜 API 버전들도 제거됐기 때문에, 브로커를 4.0으로 올리기 전에는 Java 클라이언트(Connect·Streams 포함)가 2.1 이상인지, 클라이언트를 4.0으로 올리기 전에는 브로커가 2.1 이상인지 상호 확인해야 한다.
핵심 포인트
- MirrorMaker 1(MM1)이 완전히 제거되고 Connect 기반 MM2만 지원된다.
- KIP-890 트랜잭션 프로토콜 강화로 트랜잭션마다 producer epoch가 증가해 메시지 끼어들기를 방지한다.
- 오래된 프로토콜 API 제거로 인해 브로커·클라이언트 모두 2.1 이상이어야 상호 업그레이드가 안전하다.