ZooKeeper 제거 이후, 다음 문제는 운영 가시성과 프로토콜 전환이다
Apache Kafka 4.0이 ZooKeeper를 완전히 제거하면서 KRaft 전환의 1막이 끝났다. 이제 클러스터 메타데이터를 Raft 기반으로 관리하는 것은 기본 전제다. 4.3은 그 위에서 운영자가 실제로 마주치는 문제들을 풀기 시작한다.
2026년 5월 22일 공개된 Kafka 4.3.0은 25개 KIP과 600개 이상의 커밋으로 구성된다. 이 릴리스의 중심에는 네 가지가 있다.
- Broker·로그 디렉터리 코돈: 신규 파티션 할당을 막으면서 기존 복제를 유지하는 안전한 격리 메커니즘.
- Share Group 운영 성숙: 4.0에서 preview로 들어온 Share Group에 조율 가능한 운영 파라미터가 추가됐다.
- 클래식 리밸런스 프로토콜 deprecation 1단계: 로그 경고가 시작되고, 관련 브로커 설정에 deprecated 플래그가 붙었다.
- Kafka Streams 레코드 헤더: 상태 저장소에서 헤더를 보존·접근할 수 있게 됐다.
Kafka 4.3.1이 2026년 6월 25일 나왔다. 운영 환경에서는 4.3.1 이상을 쓴다.
네 가지 변화의 위치
브로커·로그 디렉터리 코돈 (KIP-1066)
코돈(cordoning)은 Kubernetes에서 노드를 운영에서 제외할 때 쓰는 개념이다. Kafka 4.3은 같은 개념을 브로커와 로그 디렉터리에 가져왔다.
cordoned.log.dirs를 설정하면 해당 디렉터리에는 신규 파티션이 배치되지 않는다. 기존에 있는 파티션은 계속 정상 동작한다. 디커미셔닝 전 단계에서 트래픽을 자연스럽게 줄이거나, 디스크 이상이 의심되는 로그 디렉터리를 안전하게 격리하는 데 쓴다.
설정 방법은 세 가지다.
브로커 설정 파일 (server.properties)
# 쉼표로 구분, log.dirs 또는 log.dir에 정의된 경로여야 한다
cordoned.log.dirs=/data/kafka-1,/data/kafka-2런타임 변경 (Admin Client / kafka-configs.sh)
# 브로커 1번의 /data/kafka-1 코돈
kafka-configs.sh --bootstrap-server localhost:9092 \
--entity-type brokers \
--entity-name 1 \
--alter \
--add-config cordoned.log.dirs=/data/kafka-1브로커 코돈 (전체 브로커)
브로커 전체를 코돈할 수도 있다. 이 경우 해당 브로커의 모든 로그 디렉터리에 신규 파티션이 배치되지 않는다.
코돈의 효과는 즉각적이지 않다. 새 파티션이 할당될 때부터 적용된다. 이미 배치된 파티션은 그대로 존재하고 복제도 계속된다. 코돈 해제 후에는 다시 신규 파티션이 배치될 수 있다.
이전에는 비슷한 목적을 위해 log.dirs에서 경로를 제거하거나 브로커를 완전히 재시작하는 방식을 썼다. 코돈을 쓰면 재시작 없이 유연하게 배치를 제어할 수 있다.
Share Group 운영 성숙 (KIP-1240, KIP-1196)
Share Group은 4.0에서 KIP-848의 새 컨슈머 리밸런스 프로토콜 위에 도입된 '큐 방식 소비' 기능이다. 토픽 파티션 전체를 컨슈머 그룹 내에서 분배하는 기존 방식 대신, 개별 레코드를 여러 컨슈머가 가져가서 처리하고 독립적으로 승인(acknowledge)하는 모델이다. 메시지 큐와 Kafka 스트리밍을 하나의 클러스터에서 운영하고 싶을 때 유용하다.
4.0·4.2에서는 기능 자체가 GA됐지만, 운영자가 동작을 조율할 설정이 부족했다. 4.3은 그 빈틈을 채운다.
KIP-1240: Share Group 그룹 레벨 설정
| 설정 이름 | 설명 | 브로커 레벨 대응 설정 |
|---|---|---|
share.delivery.count.limit | 레코드 하나를 최대 몇 번 delivery할 수 있는지 | group.share.delivery.count.limit.{min,max} |
share.partition.max.record.locks | 파티션당 동시에 잠글 수 있는 레코드 수 상한 | group.share.record.lock.partition.limit.{min,max} |
share.renew.acknowledge.enable | acknowledge 없이 lease를 갱신할 수 있는지 여부 | — |
share.delivery.count.limit는 poison message 방어다. 처리에 계속 실패하는 레코드가 한없이 재전달되는 것을 막는다. 이 한도에 도달한 레코드는 'released to archive'로 처리돼 dead-letter 처리 경로로 보낼 수 있다.
share.partition.max.record.locks는 파티션당 락 수를 제한해 컨슈머가 너무 많은 레코드를 한꺼번에 붙잡아 두는 것을 방지한다. 처리 지연이 있는 컨슈머가 파티션 전체를 독점하는 상황을 완화한다.
KIP-1196: 코디네이터 버퍼 설정
# 그룹 코디네이터
group.coordinator.append.max.buffer.size=10485760 # 10 MiB
# Share 코디네이터
share.coordinator.append.max.buffer.size=10485760두 설정은 코디네이터가 Kafka에 상태를 기록할 때 사용하는 버퍼 크기의 상한이다. Share Group은 레코드 단위 락 상태를 코디네이터에 기록하기 때문에, 대규모 Share Group에서 코디네이터 버퍼가 병목이 될 수 있다. 버퍼 사용량을 추적하는 JMX 메트릭도 함께 추가됐다.
파티션 크기 메트릭 (KIP-1257)
운영 중 예상치 못하게 파티션이 급성장하면 클러스터 용량 계획이 틀어진다. 4.3은 파티션별로 최대 보존 크기 대비 현재 크기 비율을 JMX로 노출한다.
kafka.log:type=Log,name=LogSizePercentage,topic=<name>,partition=<n>이 메트릭은 retention.bytes가 설정된 파티션에서 의미가 있다. 비율이 높아지면 retention 정책이 곧 동작하거나 이미 용량 압박이 있다는 신호다. 이를 Prometheus나 다른 메트릭 수집 시스템으로 가져와 알림을 설정하면, 용량 소진보다 먼저 대응할 수 있다.
클래식 리밸런스 프로토콜 deprecation (KIP-1274, KIP-1237)
Kafka 4.0의 핵심 기능 중 하나는 KIP-848으로 만든 차세대 컨슈머 리밸런스 프로토콜의 GA였다. 기존 클래식 프로토콜은 컨슈머가 그룹에서 합류하거나 떠날 때마다 전체 소비를 잠깐 멈추는 "stop-the-world" 리밸런스를 일으킨다. 새 프로토콜은 이 중단을 줄이고 그룹 안정성을 높인다.
4.3에서 클래식 프로토콜 퇴장이 공식화됐다.
KIP-1274 (1단계: 경고 로그)
클래식 프로토콜을 쓰는 컨슈머가 그룹에 합류할 때 브로커가 경고 로그를 남긴다.
WARN [GroupCoordinator] Consumer group 'my-group' is using the classic rebalance protocol.
This protocol is deprecated and will be removed in a future release.
Migrate to the new consumer rebalance protocol.이 경고는 애플리케이션 코드를 바꾸지 않았어도 4.3으로 업그레이드하면 나타날 수 있다. 무시하면 Kafka 5.0에서 클래식 프로토콜 지원이 제거될 때 대응이 늦어진다.
KIP-1237: group.coordinator.rebalance.protocols deprecated
이 브로커 설정은 클래식/새 프로토콜을 명시적으로 허용하는 데 쓰였다. 4.3에서 deprecated 처리됐고 Kafka 5.0에서 제거될 예정이다.
# 아직 동작하지만 deprecated — 제거 예정
# group.coordinator.rebalance.protocols=classic,consumer이 설정 없이도 4.3에서 두 프로토콜이 모두 지원된다. 이 설정을 명시하지 않아도 기존 컨슈머는 그대로 동작한다. 하지만 클래식 프로토콜을 쓰는 컨슈머 라이브러리나 Kafka Streams 애플리케이션을 확인하고 업그레이드 계획을 세워야 한다.
Kafka Streams 레코드 헤더 보존 (KIP-1271, KIP-1285)
이전까지 Kafka Streams에서 상태 저장소(State Store)에 레코드를 넣을 때 헤더 정보가 버려졌다. 서킷 브레이커 상태, 추적 ID, 버전 메타데이터처럼 헤더에 담긴 정보가 상태 처리 흐름에서 사라졌다.
4.3은 이 문제를 두 KIP으로 해결했다.
- KIP-1271: Processor API에서 상태 저장소에 넣는 레코드 헤더를 보존하고 접근할 수 있게 확장했다.
- KIP-1285: DSL API에서도 상태 저장소가 헤더를 인식하는 "Headers-Aware State Store"를 노출했다.
이 변화는 Kafka Streams로 이벤트 주도 아키텍처를 운영하는 팀에게 실질적인 의미가 있다. 헤더에 추적 컨텍스트를 실어 전달하는 패턴(예: OpenTelemetry trace ID)이 Streams 상태 처리를 거치면서 끊기던 문제가 해소된다.
Tiered Storage 개선
Tiered Storage(계층형 스토리지)는 오래된 세그먼트를 S3·GCS 같은 원격 오브젝트 스토리지로 올려 브로커 디스크 비용을 줄이는 기능이다. 4.3은 세 가지 개선을 더했다.
KIP-1235: remote.log.metadata.topic.min.isr 설정
__remote_log_metadata 내부 토픽의 min.insync.replicas 기본값을 2로 올리는 신규 브로커 설정이다. 이전에는 이 내부 토픽이 기본 min.isr=1로 운영돼 리더만 살아 있어도 쓸 수 있었다. 기본값 수정으로 복제 안전성이 높아졌지만, 단일 노드 개발 환경이나 리플리카 수가 적은 설정에서는 주의가 필요하다.
KIP-1208: remote.log.metadata.admin 설정 prefix
Tiered Storage의 RemoteLogMetadataManager가 내부적으로 쓰는 admin client 설정을 remote.log.metadata.admin. prefix로 분리했다. 이전에는 다른 컴포넌트 설정과 네임스페이스가 섞여 충돌할 수 있었다.
# 이전 방식 (모호, 충돌 가능)
# remote.log.metadata.xxx=...
# 4.3 이후 권장 방식
remote.log.metadata.admin.bootstrap.servers=kafka1:9092,kafka2:9092
remote.log.metadata.admin.request.timeout.ms=30000follower.fetch.last.tiered.offset.enable
이 신규 설정을 true로 켜면 새 팔로워가 원격 스토리지에서 데이터를 bootstrap할 때 last tiered offset을 시작점으로 사용한다. 기존에는 팔로워가 원격 스토리지에서 오래된 세그먼트까지 다 가져오려 할 수 있었다. 이 설정이 있으면 불필요한 원격 다운로드를 줄이고 팔로워 복구 속도를 높일 수 있다.
업그레이드 체크리스트
버전
- [ ] 4.3.0 대신 4.3.1 이상을 사용하는가?
- [ ] KRaft 모드로 이미 운영 중인가? (4.0 이상이라면 당연히 그렇다)
클래식 프로토콜
- [ ] 클러스터 업그레이드 후 브로커 로그에서 클래식 프로토콜 경고가 나타나는지 확인했는가?
- [ ] 클래식 프로토콜을 쓰는 컨슈머 클라이언트 라이브러리 버전을 확인했는가?
- [ ]
group.coordinator.rebalance.protocols설정 사용을 제거하는 계획이 있는가? - [ ] Kafka Streams 애플리케이션이 새 리밸런스 프로토콜을 지원하는 클라이언트 버전을 쓰는가?
브로커 코돈
- [ ] 디커미셔닝 절차에
cordoned.log.dirs또는 브로커 코돈 단계를 추가했는가? - [ ] 코돈된 로그 디렉터리에 기존 파티션은 계속 복제되고 있는지 확인하는 지표가 있는가?
Share Group (사용하는 경우)
- [ ]
share.delivery.count.limit를 설정해 poison message 루프를 방지했는가? - [ ]
share.partition.max.record.locks로 파티션별 락 수를 조율했는가? - [ ] 코디네이터 버퍼 메트릭을 모니터링하고 있는가?
Tiered Storage (사용하는 경우)
- [ ]
__remote_log_metadata토픽의 리플리카 수가 새 기본min.isr=2를 지원하는가? - [ ] admin client 설정을
remote.log.metadata.admin.prefix로 이전했는가? - [ ]
follower.fetch.last.tiered.offset.enable을 켜고 팔로워 bootstrap 시간을 비교했는가?
Kafka Streams (사용하는 경우)
- [ ] 레코드 헤더가 상태 저장소를 거쳐도 보존되는지 확인이 필요한 파이프라인을 점검했는가?
- [ ] OpenTelemetry나 분산 추적 컨텍스트를 헤더로 전달하는 경우 Streams 업그레이드 후 헤더 연속성을 검증했는가?
파티션 크기 메트릭
- [ ]
LogSizePercentageJMX 메트릭을 모니터링 시스템에 추가했는가? - [ ]
retention.bytes가 설정된 중요 토픽에 크기 임박 알림 임계값을 설정했는가?
정리
Kafka 4.3의 변화는 새로운 아키텍처 도입이 아니라 기존 기능의 운영 성숙이다. ZooKeeper가 없어진 자리에서, 이제 운영자에게 필요한 것은 더 세밀한 통제권과 더 많은 가시성이다.
브로커 코돈은 롤링 유지보수와 디커미셔닝을 더 안전하게 만든다. Share Group 설정은 preview 단계의 미성숙한 운영 통제를 채워 줬다. 클래식 프로토콜 경고는 조용히 진행되던 프로토콜 전환의 마감 시계를 가시화한다. Tiered Storage 개선은 원격 스토리지를 실제 프로덕션에서 신뢰하기 위한 작은 단계들이다.
운영자가 지금 해야 할 일은 클래식 프로토콜 경고를 확인하고, 관련 클라이언트와 Streams 앱 업그레이드 계획을 세우는 것이다. Kafka 5.0에서 클래식 프로토콜이 제거되기 전에 마이그레이션을 완료해야 한다.
References
- Apache Kafka 4.3.0 Release Announcement — kafka.apache.org, 2026-05-22
- Apache Kafka 4.3.1 Release Announcement — kafka.apache.org, 2026-06-25
- Apache Kafka 4.3 released: 25 KIPs — Confluent Blog
- Apache Kafka 4.3.0: A guide for platform engineers — Factor House
- KIP-1066: Mechanism to cordon brokers and log directories — Apache Kafka Confluence
- KIP-1274: Deprecate classic rebalance protocol in KafkaConsumer — Apache Kafka Confluence
- KIP-848: The Next Generation of the Consumer Rebalance Protocol — Confluent Blog
- Apache Kafka 4.3.0: What's New and What Changed — Zeliot
- Apache Kafka 4.0 Release: Default KRaft, Queues, Faster Rebalances — Confluent
- Kafka Apache Kafka 4.3.0 News — Gravitee Blog