Apache Kafka 4.0 新特性解读与迁移指南
从Kafka 4.0正式移除ZooKeeper出发,覆盖KRaft迁移、Java版本变更与消息格式淘汰等关键变化
Apache Kafka 4.0 于 2024 年 10 月正式发布,这是 Kafka 发展历程中的一个里程碑版本——ZooKeeper 依赖被彻底移除,KRaft 模式成为唯一的元数据管理方式。对于仍在使用 ZooKeeper 模式的 Kafka 集群,这意味着必须在升级到 4.0 之前完成 KRaft 迁移,否则将无法享受 4.0 及后续版本的新特性和安全更新。Confluent 在其官方博客中明确指出,Kafka 3.5 已经废弃 ZooKeeper 支持,4.0 彻底移除,社区资源将完全聚焦于 KRaft 模式的演进。本文从 Kafka 4.0 的核心变更出发,提供生产环境迁移的实操指南。
ZooKeeper 移除的技术背景
Kafka 对 ZooKeeper 的依赖始于 2011 年项目初期。ZooKeeper 负责管理 Kafka 集群的元数据,包括 Broker 注册、Topic 配置、分区 Leader 选举和 ACL 权限等。但随着 Kafka 集群规模增长,ZooKeeper 的局限性日益突出:元数据存储存在单点瓶颈,Controller 切换时间随集群规模线性增长,运维需要同时维护两套独立的分布式系统。
KIP-500(Kafka Improvement Proposal 500)提出了用 KRaft 替代 ZooKeeper 的方案。KRaft 基于 Raft 共识算法,将元数据管理内嵌到 Kafka 自身的 Controller 节点中,不再依赖外部组件。KRaft 从 Kafka 3.3.1 版本开始标记为生产可用,经过多个版本的迭代验证,在 4.0 中成为唯一模式。
KRaft 相比 ZooKeeper 架构的核心优势包括:Controller 切换时间从分钟级降低到秒级(因为元数据已在 Controller 节点本地存储,无需跨网络同步);集群可支持的 Topic 数量上限从数十万级提升到百万级(消除了 ZooKeeper 的 znode 存储瓶颈);运维复杂度大幅降低(不再需要独立部署和维护 ZooKeeper 集群)。
4.0 版本的其他关键变更
除了 ZooKeeper 移除外,Kafka 4.0 还包含若干需要在迁移前了解的变更。
Java 版本要求从 Java 8 和 11 提升到 Java 17 及以上。这意味着如果当前集群运行在 Java 8 或 Java 11 上,需要先升级 JVM 版本。建议直接升级到 Java 21,这是当前 LTS 版本,性能和安全性都优于 Java 17。
消息格式方面,Kafka 4.0 移除了对消息版本 V0 和 V1 的支持。V0 和 V1 是 Kafka 早期的存储格式,如果 Topic 创建时间足够早(通常在 Kafka 0.10 之前),可能仍在使用这两种格式。迁移前需要通过 kafka-log-dirs.sh 工具检查所有 Topic 的消息格式版本,将使用 V0 或 V1 的 Topic 通过 kafka-configs.sh 升级到 V2 格式。
旧版消费者协议(Group Management Protocol v0 和 v1)被移除。使用这些旧协议的客户端需要升级。在实践中,绝大多数现代 Kafka 客户端库(如 Java 的 kafka-clients 2.0 以上版本)已经使用新版协议,但需要确认环境中的所有客户端版本。
大数据基础平台 EasyMR
统一存储、计算与运维,支撑批、流、OLAP 与湖仓一体的国产化大数据底座平台
迁移策略选择
Kafka 官方提供了两种 KRaft 迁移路径:原地迁移(In-Place Migration)和新建集群(Greenfield Setup)。
原地迁移适合已有稳定运行的 ZooKeeper 集群、且希望最小化数据搬迁成本的场景。迁移过程分为六个步骤:第一步,升级 Kafka 到 3.9.x 版本(这是支持 ZooKeeper 和 KRaft 双模式的桥接版本)。第二步,部署 KRaft Controller 节点(至少 3 个,组成 Controller Quorum)。第三步,在 Controller 配置中启用迁移模式(设置 zookeeper.metadata.migration.enable=true)。第四步,滚动重启 Broker,将其从 ZooKeeper 模式切换到 KRaft 模式——这一步需要将 broker.id 替换为 node.id 并添加 process.roles=broker,同时移除 ZooKeeper 相关配置。第五步,关闭迁移模式,从 Controller 配置中移除 zookeeper.metadata.migration.enable 并重启 Controller。第六步,下线 ZooKeeper 集群。
整个滚动重启过程中,Kafka 集群持续提供读写服务,不会出现停机。但每一步之间建议留出足够的观察期(至少 24 小时),确认集群状态稳定后再进入下一步。
新建集群适合以下情况:现有集群硬件老旧需要整体更换、集群规模较小重新搭建成本更低、或者希望借此机会优化 Topic 和 Partition 的布局。新建集群的步骤更简单:部署 KRaft 模式的 Kafka 集群,然后通过 MirrorMaker 2 或 Confluent Replicator 将旧集群的数据同步到新集群,切换消费端和生产端的地址后下线旧集群。
迁移前的检查清单
迁移前的准备工作决定了迁移的成败。以下是必须完成的检查项。
确认所有 Topic 的消息格式版本为 V2。通过执行 kafka-log-dirs.sh --bootstrap-server ``broker`:9092 --describe 查看每个 Topic 的 logStartVersion 字段。如果发现 V0 或 V1,使用 kafka-configs.sh --alter --add-config message.format.version=2.0 --entity-type topics --entity-name topic_name` 升级。
确认 Kafka 客户端版本兼容。Java 客户端建议升级到 3.0 以上版本。对于使用 Confluent Schema Registry 的环境,需要确保 Schema Registry 版本支持 KRaft 模式下的 Schema 管理。对于使用 Kafka Connect 的环境,需要确认所有 Connector 的版本支持 KRaft 模式。
评估 ZooKeeper 集群的当前状态。如果 ZooKeeper 本身已经存在问题(如磁盘空间不足、会话超时频繁),需要在迁移前先修复这些问题,否则迁移过程中的元数据同步可能受影响。
备份 Kafka 集群的配置文件和 Topic 元数据。虽然迁移过程理论上可以回滚,但在开始迁移前做好完整备份是基本的运维纪律。
数据治理
统一标准、质量、安全与资产管理,沉淀高质量数据集,支撑经营决策、监管合规与 AI 应用。
迁移后的验证
迁移完成后需要执行一系列验证确保集群状态正常。
基础连通性验证:使用 kafka-broker-api-versions.sh 检查所有 Broker 的 API 版本是否正常返回。使用 kafka-topics.sh 创建一个测试 Topic 并验证读写正常。
元数据完整性验证:对比迁移前后 Topic 的数量、Partition 分布和副本配置是否一致。使用 kafka-replica-verification.sh 检查所有 Partition 的副本一致性。
客户端兼容性验证:使用升级后的客户端库连接到 KRaft 模式的集群,执行生产消费操作,确认没有兼容性问题。
监控指标验证:检查 Controller 节点的元数据加载时间、Broker 的请求延迟和 ISR 变化频率等指标,与迁移前的基线对比。KRaft 模式下 Controller 的元数据加载时间应该在秒级完成,远快于 ZooKeeper 模式的分钟级。
Kafka 3.9.x 作为桥接版本,AWS 的 MSK 服务已经承诺为其提供至少 2 年的扩展支持(自 2025 年 4 月发布起计算),为尚未完成迁移的用户提供了缓冲期。但这个缓冲期不是无限的——一旦 Kafka 5.0 发布,3.9.x 将不再获得社区支持,届时未迁移的集群将面临安全风险。
迁移过程中的风险与应对
迁移过程中最大的风险是 Controller 切换时的短暂不可用。在原地迁移过程中,当启用迁移模式后首次切换到 KRaft 元数据存储时,Controller 需要从 ZooKeeper 同步全量元数据到本地,这个过程可能持续数分钟到数十分钟(取决于 Topic 和 Partition 数量),期间集群的 Leader 选举和 Partition 管理会暂停。
应对措施是选择业务低峰期执行这一步操作,同时提前将所有 Broker 的 Leader 分布调整为均衡状态,减少迁移过程中触发 Leader 选举的概率。
另一个常见风险是迁移过程中部分 Broker 已经切换到 KRaft 模式而部分仍在 ZooKeeper 模式时的混合状态兼容性问题。官方文档明确指出混合模式只在迁移过程中临时支持,不应长期维持。建议在启动混合模式迁移后,集中时间窗口完成所有 Broker 的切换,避免长时间处于混合状态。


