集群升级与滚动重启实践

系统讲解 Kafka 集群升级与滚动重启实践:ZooKeeper 到 KRaft 的迁移路径、升级前兼容性检查清单、滚动重启的正确顺序与 ISR 观察、inter.broker.protocol 与 log.message.format 版本控制、客户端协议升级、监控指标与回滚预案

「Kafka 升级」在生产环境是高风险操作:一个 broker 重启期间,它承载的所有分区副本数临时减少,若同时有副本落后或网络抖动,就可能触发 ISR 收缩甚至分区不可用。而「滚动重启」——逐个重启 broker——正是把这种风险分摊到每一步的标准手法,前提是每一步都确认集群恢复健康再走下一步。

本文覆盖从 ZooKeeper 到 KRaft 的迁移、升级前的兼容性检查、滚动重启的正确顺序、版本参数(inter.broker.protocol.version / log.message.format.version)的两阶段升级法,以及监控与回滚——目标是把「升级」从「赌运气」变成「有 checklist 的工程流程」。

1. 两条升级路径

1.1 ZooKeeper 模式(传统)

集群元数据(topic、分区、ISR、ACL)存储在 ZooKeeper
broker 与 ZK 交互,Controller 由 ZK 选举产生

1.2 KRaft 模式(Kafka 3.3+ 生产可用,4.0 移除 ZK)

元数据作为「元数据日志」存在 Kafka 自身(__cluster_metadata topic)
Controller 由 Raft 协议选举,无需 ZK
优点:启动快、元数据扩展性好、运维组件少

1.3 路径选择

现状目标路径
旧版 ZK 集群同架构新版原地滚动升级
ZK 集群KRaft迁移(ZK → KRaft)
KRaft 集群新版 KRaft原地滚动升级

一句话:KRaft 是终局(Kafka 4.0 起移除 ZooKeeper),但迁移有专门流程;同架构升级是相对低风险的滚动重启,跨架构迁移要单独规划。KRaft 架构详见 KRaft 模式 。

2. 升级前检查清单

2.1 兼容性检查

① 目标版本与当前版本的「升级路径」是否直达(避免跨太多大版本)
② 客户端协议版本兼容(老客户端能否连新 broker)
③ 消息格式版本(log.message.format.version)是否需要升级
④ 使用的功能是否被废弃(如 ZK 相关 API、旧版工具)
⑤ 依赖的插件(Connector、Schema Registry)版本兼容

2.2 集群健康基线

# 1. 确认所有分区有完整 ISR
kafka-topics.sh --bootstrap-server kafka:9092 --describe --under-replicated-partitions

# 2. 确认无 offline 分区
kafka-topics.sh --bootstrap-server kafka:9092 --describe --unavailable-partitions

# 3. 确认 controller 健康
zookeeper-shell.sh zk:2181 get /controller   # ZK 模式

红线:任何 under-replicated 或 offline 分区未清零前,不得开始升级——带着问题滚动重启 = 雪上加霜。

2.3 容量与流量确认

① 升级窗口选在低峰期(消费 Lag 低、生产流量低)
② 确认磁盘空间充足(升级可能触发日志滚动/重建)
③ 确认无正在执行的大规模重平衡或分区迁移

2.4 备份与回滚预案

① 备份关键配置(server.properties、topic 配置)
② 确认「回滚到旧版本」的步骤可行(消息格式未升级则可回滚)
③ 准备好监控大盘与告警

一句话:升级前最重要的动作是「确认集群健康」——under-replicated-partitions 与 unavailable-partitions 必须清零;带着不健康的集群滚动重启,等于把风险放大 N 倍。

3. 滚动重启的正确顺序

3.1 核心原则

每次只重启一个 broker
重启后等待:该 broker 的分区 ISR 恢复完整
确认健康后再重启下一个

3.2 单节点重启流程

# ① 重启前:确认该节点分区 ISR 完整
kafka-topics.sh --bootstrap-server kafka:9092 \
  --describe --under-replicated-partitions | grep <broker-id>

# ② 优雅停止 broker(发 SIGTERM,让它先卸任 controller / 完成副本同步)
kill -SIGTERM <kafka-pid>
# 等待进程退出,日志出现 "shutdown completed"

# ③ 启动新版本 broker
./bin/kafka-server-start.sh -daemon config/server.properties

# ④ 等待 ISR 恢复:观察该节点的分区重新同步
#    用监控或循环检查 until under-replicated 为空

3.3 优雅关闭 vs 强杀

SIGTERM:broker 优雅关闭——卸任 controller、刷盘、通知其他 broker
SIGKILL:强杀——可能触发更长的恢复、controller 重选

原则:永远用 SIGTERM,给 broker 足够时间优雅退出;controlled.shutdown.enable=true(默认)让 broker 主动迁移 controller 角色。

3.4 controller 重启的特殊性

若重启的是 controller 节点:
  → 触发 controller 选举 → 元数据重新加载 → 短暂元数据操作阻塞
建议:先确认哪些是 controller,必要时先「转移 controller」再重启
# 查看当前 controller
zookeeper-shell.sh zk:2181 get /controller

3.5 自动化滚动脚本骨架

#!/usr/bin/env bash
set -euo pipefail
BROKERS="1 2 3 4 5"

for id in $BROKERS; do
  echo ">>> restarting broker $id"
  ssh broker-$id "sudo systemctl stop kafka"
  # 等待该节点分区 ISR 恢复
  until is_isr_healthy "$id"; do sleep 10; done
  ssh broker-$id "sudo systemctl start kafka"
  # 等待节点上线且 ISR 完整
  until is_broker_up "$id" && is_isr_healthy "$id"; do sleep 10; done
  echo ">>> broker $id healthy, sleep 60s before next"
  sleep 60
done

一句话:滚动重启的黄金法则是**「一次一个 + 每次等 ISR 恢复」**——用 SIGTERM 优雅关闭,重启后确认该节点分区重新同步完整,再动下一个。

4. 版本参数的两阶段升级

4.1 三个关键版本参数

inter.broker.protocol.version=3.5    # broker 间通信协议版本
log.message.format.version=3.5       # 消息落盘格式版本

作用:这两个参数让新旧 broker 混合运行成为可能——即使升级了二进制,只要协议/格式版本没升,行为仍兼容旧版。

4.2 两阶段升级法(关键!)

阶段一:升级二进制
  ① 保持 inter.broker.protocol.version = 旧版本
  ② 逐个滚动重启所有 broker(新二进制 + 旧协议)
  ③ 此时集群可随时回滚(回滚 = 换回旧二进制重启)

阶段二:升级协议与格式
  ④ 全部 broker 就绪后,改 inter.broker.protocol.version = 新版本
  ⑤ 再滚动重启一次(协议生效)
  ⑥ 改 log.message.format.version = 新版本
  ⑦ 再滚动重启(格式生效,此步后不可回滚)

核心价值:阶段一之后、阶段二之前,是回滚的最后窗口——一旦 log.message.format.version 升级,旧版本 broker 将无法读取新格式消息,回滚不再可能。

4.3 参数对照

参数含义升级时机
inter.broker.protocol.versionbroker 间通信协议阶段二第 ④ 步
log.message.format.version消息磁盘格式阶段二第 ⑥ 步(最后)
log.message.timestamp.type时间戳类型需单独确认

一句话:两阶段升级法把「二进制升级」与「协议升级」解耦——阶段一只换二进制(可回滚),阶段二才升协议与格式(不可逆);升级前务必确认「回滚窗口」在哪里。

5. 客户端与消息格式

5.1 客户端协议兼容

Kafka 的协议向后兼容:新 broker 能服务旧客户端
但反向不成立:旧 broker 无法服务「使用新特性」的新客户端

策略:先升 broker,再升客户端——broker 先支持新协议,客户端才有升级空间。

5.2 客户端升级注意

① 新版客户端可能默认启用幂等生产者、新分区器 → 行为变化
② 序列化格式(Schema)需向后兼容,别在升级时顺带改 Schema
③ 消费组协议(如 cooperative-sticky)变化可能触发一次全量再平衡

5.3 消息格式版本的影响

# 若升级 log.message.format.version
log.message.format.version=3.5
影响:新写入的消息用新格式
代价:旧 broker 无法读取 → 不可回滚
前提:所有消费者客户端都支持新格式

5.4 升级中的 rebalance 风险

broker 重启 → 消费者感知到分区变化 → 可能触发消费组再平衡
频繁再平衡 → 消费停顿
对策:升级窗口选低峰、确认消费组稳定、避免升级时同时改消费端

一句话:先 broker 后客户端是铁律;log.message.format.version 是不可逆的最后一刀——升级前确认所有消费者都能读新格式。

6. 监控与回滚

6.1 升级期间的监控指标

broker:under-replicated 分区数、offline 分区数、ActiveControllerCount
消费:消费 Lag、消费组再平衡次数
系统:磁盘 IO、网络、GC 暂停
# 关键:升级全程盯着未同步分区
watch -n 5 'kafka-topics.sh --bootstrap-server kafka:9092 \
  --describe --under-replicated-partitions | wc -l'

6.2 健康判定标准

可以继续下一步的标志:
  - under-replicated-partitions == 0
  - unavailable-partitions == 0
  - 消费 Lag 回落到基线
  - ActiveControllerCount == 1

6.3 回滚预案

阶段可否回滚回滚方式
阶段一(仅换二进制)可换回旧二进制滚动重启
阶段二(升协议)可改回旧协议版本重启
升级消息格式后不可只能向前(恢复旧格式需重建)

6.4 高可用保障

升级期间的分区副本容错依赖 集群高可用设计 ;controller 的选举与故障转移细节见 副本与 Controller 内部机制 。

一句话:升级的安全网是监控——全程盯 under-replicated 与 offline 分区;回滚窗口在消息格式升级之前,之后只能向前。

7. 常见坑

7.1 高频事故清单

坑现象对策
带着 under-replicated 升级分区不可用升级前清零
一次重启多个 brokerISR 大面积收缩一次一个
SIGKILL 强杀恢复慢、controller 重选用 SIGTERM
直接升消息格式无法回滚两阶段升级
升级时改 Schema消费端解析失败Schema 单独演进
未确认客户端版本老客户端连不上先 broker 后客户端
忽略 controller 重启元数据操作阻塞先转移 controller

7.2 升级 checklist

□ 目标版本与升级路径确认
□ 集群健康:under-replicated=0、offline=0
□ 低峰窗口、磁盘充足、无进行中的迁移
□ 备份配置、明确回滚步骤与窗口
□ 两阶段参数策略(协议/格式最后升)
□ 客户端版本兼容确认
□ 监控大盘就绪、告警开启
□ 逐个滚动、每次等 ISR 恢复
□ 升级后验证:收发、消费 Lag、Controller 唯一

7.3 升级后验证

# 端到端收发验证
kafka-console-producer.sh --bootstrap-server kafka:9092 --topic smoke-test <<< "hello"
kafka-console-consumer.sh --bootstrap-server kafka:9092 --topic smoke-test \
  --from-beginning --max-messages 1

日常运维监控指标详见 Kafka 监控与运维 。

8. 小结

阶段关键动作风险控制
准备健康检查、备份、窗口选择不健康不升级
阶段一换二进制、滚动重启保留回滚窗口
阶段二升协议、升格式、再重启格式最后升
验证收发冒烟、指标回归监控全程
回滚按阶段判断可行性格式升级前可回

一句话记住:Kafka 升级的本质是**「用滚动重启把风险分摊,用版本参数把不可逆推迟」**——一次一个 broker、每次等 ISR 恢复、协议与格式两阶段最后升,全程盯住 under-replicated 与 offline 分区。升级不是一次操作,而是一套有回滚窗口的流程;想清楚「哪一步之后回不去了」,才是安全的升级。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「kafka」更多文章

  1. Kafka 应用测试策略:Testcontainers 与集成测试
  2. 压缩算法选型:lz4、zstd、snappy 与 gzip
  3. Kafka 与 Flink 流批一体集成