一、先说结论
- 最低门槛:所有 Java 客户端(含 Streams/Connect)与目标 broker 之间的互通,版本下限都是 2.1。
- 控制面:Kafka 4.0 仅支持 KRaft(无 ZooKeeper)。要升 4.0,集群必须已经在 KRaft(≥3.3.x);ZK 集群需先迁移至 KRaft。
- Java 要求:客户端/Streams ≥ Java 11;Broker/Connect/工具 ≥ Java 17。
- 最终化(finalize)后才会开启 4.0 的关键协议(如 KIP-848、KIP-890)。一旦启用新协议,降级边界会收紧(例如消费组启用 KIP-848 后最多只能降到 3.4.1+)。
- 元数据变更:4.0 包含元数据格式更新 → 不支持元数据降级(跨有变更的版本链路无法回退元数据)。
二、兼容性都涵盖哪些维度?
- 协议兼容:客户端 ↔ broker 的请求/响应版本是否互认。
- API/CLI 兼容:被移除或更名的客户端 API、管理命令与选项。
- 运行时兼容:JDK/Scala、日志框架(Log4j→Log4j2)等。
- 数据/元数据兼容:主题格式、元数据日志、集群特性(KRaft)与“最终化”。
- 行为兼容:再均衡、事务语义、复制与选主行为调整。
三、实战速查矩阵(以官方矩阵为准,下面为工程化指引)
组合 | 互通性 | 备注(关键前提 / 限制) |
---|---|---|
Client 4.0 ↔ Broker 2.1~3.9(KRaft/早期) | ✅ 通常可用 | 4.0 移除老协议版本;要求 broker ≥2.1。ZK 模式不在 4.0 支持范围内(目标若为 4.0 broker 必须 KRaft)。 |
Client 2.1~3.x ↔ Broker 4.0(KRaft) | ✅ 通常可用 | 升 broker 前,先确保所有客户端 ≥2.1。最终化前先灰度观察。 |
Client <2.1 ↔ 任意 | ❌ 风险高 | 4.0 移除了多项旧协议/接口;请先把客户端就地升级到 ≥2.1。 |
ZK 集群 → Broker 4.0 | ❌ 不支持 | 必须先迁移到 KRaft(建议到 3.9.x),再升 4.0。 |
启用 KIP-848 新再均衡 后降级 | ⚠️ 受限 | 消费组一旦使用新协议,集群只能降到 3.4.1+。 |
元数据降级(4.0 ↘︎ 旧版) | ❌ 不支持 | 4.0 元数据有变更;有变更链路无法做 metadata downgrade。 |
提示:上表为实践速记。进行变更前,请始终以官方兼容性矩阵为准做最终裁决。
四、升级顺序怎么排才稳?
路线 A:先客户端,后服务端(多数团队首选)
目标:把“协议压力”前置到应用侧,便于灰度与回滚。
步骤:
- 把所有客户端(含 Streams/Connect)先升级到 ≥2.1(或直接 4.0 客户端)
- 观察一段时间 → 再滚动升 Broker 到 4.0(KRaft)
- 稳定后再执行最终化开启 4.0 新协议
好处:应用灰度可控;未 finalize 前回退空间更大。
路线 B:先服务端,后客户端(版本下限满足时可选)
- 前提:所有客户端已 ≥2.1。
- 步骤:滚动升 Broker(KRaft)→ 验证 → 最后再 finalize → 再推进客户端到 4.0。
- 适合:Broker 托管在统一平台、升级窗口更集中。
共同要点:最终化永远放最后;把它当“新协议与元数据变更”的发布开关。
五、易踩坑的兼容性变化(必须逐条过)
客户端 API 与行为
- Consumer:
poll(long)
被移除 → 改用poll(Duration)
(不会超时外阻塞等待分配);committed(TopicPartition)
→ 改用committed(Set<...>)
。 - Producer:
linger.ms
默认 0→5;enable.idempotence
不再因max.in.flight>5
自动降级;sendOffsetsToTransaction(..., String)
移除。 - Admin:
alterConfigs
移除 → 用incrementalAlterConfigs
。 - Streams:3.6 及更早标记弃用的多数公开 API 被移除(少数例外)。
命令行与工具
- 统一用
--bootstrap-server
(仅逗号分隔支持);--whitelist
等若干旧参数移除或更名(用--include
等)。 - MirrorMaker 1 移除 → 用 MM2(Connect);Connect 多处 white/blacklist → include/exclude。
运行时与安全
- 仅 KRaft;JDK 要求提升(客户端/Streams ≥11;Broker/Connect/工具 ≥17)。
- 日志框架迁移到 Log4j2;
KafkaLog4jAppender
移除。 - 新增系统属性:
org.apache.kafka.sasl.oauthbearer.allowed.urls
(默认空,OAUTHBEARER/JWKS 需显式设置)。
协议与元数据
- KIP-848(新再均衡协议)与 KIP-890(事务加固)在最终化后生效;
- 元数据格式在 4.0 有变更 → 不支持元数据降级。
六、回滚与降级边界
未最终化(未 finalize):一般更易回退(取决于已变更的范围)。
已最终化:
- 若消费组已用 KIP-848 → 只能降到 3.4.1+
- 元数据变更跨版本 → 无法做 metadata downgrade
策略:把 finalize 延后,留足观察与回退窗口。
七、上线前后核对清单(Checklist)
上线前
- 盘点所有客户端版本,确保 ≥2.1(含 Streams/Connect)
- 校验 JDK:客户端/Streams ≥11,Broker/Connect/工具 ≥17
- 若目标 4.0:确认KRaft 已就绪(ZK 集群需先迁移)
- 预演 CLI 与脚本:
--bootstrap-server
、参数更名/移除项 - 压测基线:吞吐、端到端延迟、Lag、ISR、控制面指标
灰度与观测
- 小批量升级并观察 24–72h:错误率、超时、重试、DLT
- 重点关注再均衡时延、事务提交情况、复制与选主稳定性
- 日志与指标:Log4j2 配置、OAUTHBEARER 白名单 URL
最终化后
- 确认已启用 KIP-848/KIP-890 且行为符合预期
- 标注降级边界与应急 Runbook(3.4.1+、metadata 不降)
- 更新团队文档与兼容性矩阵链接,固化经验
八、迁移代码速看(三段示例)
Consumer:poll(Duration)
替代 poll(long)
var consumer = new KafkaConsumer<String, String>(props);
consumer.subscribe(List.of("demo"));
while (true) {
var records = consumer.poll(Duration.ofSeconds(1)); // 不在超时外等待分配
records.forEach(r -> {/* ... */});
}
Producer 事务:同时处理两类异常(KIP-890 建议)
producer.initTransactions();
try {
producer.beginTransaction();
producer.send(new ProducerRecord<>("tx", key, val));
producer.commitTransaction();
} catch (TimeoutException | TransactionAbortableException e) {
producer.abortTransaction(); // 保持 Exactly-Once
}
Admin:incrementalAlterConfigs
替代 alterConfigs
try (Admin admin = Admin.create(props)) {
var res = new ConfigResource(ConfigResource.Type.TOPIC, "demo");
var op = new AlterConfigOp(new ConfigEntry("min.insync.replicas", "2"), AlterConfigOp.OpType.SET);
admin.incrementalAlterConfigs(Map.of(res, List.of(op))).all().get();
}
九、落地建议
- 矩阵常看常新:把官方兼容性矩阵挂在团队 Wiki 首页,变更先看它。
- “先灰度、后最终化” 当作铁律;finalize = 打开“强协议/元数据开关”。
- 工具链自检:CI、脚本、运维面板全面适配 4.0 的参数与指标。
- 以“最小可用组合”推进:先过门槛(≥2.1、KRaft、JDK),再逐步享用 4.0 新能力。