# Kafka 2.2.1 → 4.3.1 升级指南
根据你给出的三份真实配置,升级路径是:
```text
kafka_2.12-2.2.1
ZooKeeper模式
↓
kafka_2.12-3.9.1
KRaft静态Controller仲裁
↓
kafka_2.13-4.3.1
先保持静态仲裁启动
↓
升级metadata.version和kraft.version
↓
改成动态Controller仲裁配置
```
你当前已经到达:
```text
Kafka程序版本:4.3.1
metadata.version:4.0-IV3
kraft.version:1
```
但当前 4.3.1 配置仍然是:
```properties
controller.quorum.voters=1@private001v.tq.cztt.qianxin-inc.cn:29093
```
由于 `kraft.version=1` 已经生效,下一次重启前应改成:
```properties
controller.quorum.bootstrap.servers=private001v.tq.cztt.qianxin-inc.cn:29093
```
下面是完整升级过程。
## 一、升级前必须明确数据处理方式
从 2.2.1 ZooKeeper 直接执行 KRaft `format`,属于停机转换或重建,不是官方在线元数据迁移。
如果旧集群中的以下信息必须完整保留:
- Topic 元数据
- Topic 配置
- ACL
- Consumer Group Offset
- 分区 Leader 和副本信息
- Producer ID 及事务状态
应先用 Kafka 3.9 执行 ZooKeeper → KRaft 正式迁移。
如果旧实例本身没有重要数据,或者已经通过其他方式迁移数据,则可以使用你当前采用的停机格式化方式。
以下过程按照你当前的"单节点停机转换"整理。
## 二、2.2.1 升级前检查
### 1. 确认旧 Kafka 进程
```bash
cd /qaxdata/s/services/kafka/kafka_29092/kafka_2.12-2.2.1
bin/kafka-topics.sh --version
ps -ef | grep '[k]afka.Kafka'
```
### 2. 记录旧 Cluster ID
```bash
bin/zookeeper-shell.sh \
private001v.tq.cztt.qianxin-inc.cn:22181/kafka29092 \
get /cluster/id
```
保存返回的 Cluster ID。
如果返回的是:
```text
SV6NxEtETaO5x7G0wzq3NQ
```
那么 KRaft 格式化时继续使用这个 ID。
### 3. 导出 Topic 和消费组信息
```bash
bin/kafka-topics.sh \
--bootstrap-server private001v.tq.cztt.qianxin-inc.cn:29092 \
--list
```
```bash
bin/kafka-topics.sh \
--bootstrap-server private001v.tq.cztt.qianxin-inc.cn:29092 \
--describe
```
```bash
bin/kafka-consumer-groups.sh \
--bootstrap-server private001v.tq.cztt.qianxin-inc.cn:29092 \
--all-groups \
--describe
```
SASL 环境需要传入已经配置认证信息的客户端文件。
### 4. 停止后备份
先正常停止 Kafka:
```bash
bin/kafka-server-stop.sh
```
确认退出:
```bash
pgrep -af 'kafka.Kafka'
```
备份配置:
```bash
cd /qaxdata/s/services/kafka/kafka_29092
cp -a kafka_2.12-2.2.1/config \
config-2.2.1-backup
```
对下面目录做完整备份或磁盘快照:
```text
/qaxdata/s/services/kafka/kafka_29092/data
```
同时备份 ZooKeeper 数据。
## 三、2.2.1 配置转换为 3.9.1 KRaft 配置
旧版 ZooKeeper 配置核心内容:
```properties
broker.id=1
zookeeper.connect=private001v.tq.cztt.qianxin-inc.cn:22181/kafka29092
authorizer.class.name=kafka.security.auth.SimpleAclAuthorizer
```
转换为 3.9.1 KRaft 后:
```properties
node.id=1
process.roles=broker,controller
controller.quorum.voters=1@private001v.tq.cztt.qianxin-inc.cn:29093
authorizer.class.name=org.apache.kafka.metadata.authorizer.StandardAuthorizer
```
### Kafka 3.9.1 完整配置
文件:
```text
/qaxdata/s/services/kafka/kafka_29092/kafka_2.12-3.9.1/config/server.properties
```
内容:
```properties
# Node and roles
node.id=1
process.roles=broker,controller
# Static KRaft controller quorum
controller.quorum.voters=1@private001v.tq.cztt.qianxin-inc.cn:29093
controller.listener.names=CONTROLLER
# Listeners
listener.security.protocol.map=CONTROLLER:PLAINTEXT,SASL_PLAINTEXT:SASL_PLAINTEXT
listeners=SASL_PLAINTEXT://0.0.0.0:29092,CONTROLLER://0.0.0.0:29093
advertised.listeners=SASL_PLAINTEXT://private001v.tq.cztt.qianxin-inc.cn:29092
inter.broker.listener.name=SASL_PLAINTEXT
# SASL
sasl.enabled.mechanisms=PLAIN
sasl.mechanism.inter.broker.protocol=PLAIN
# Authorization
authorizer.class.name=org.apache.kafka.metadata.authorizer.StandardAuthorizer
allow.everyone.if.no.acl.found=true
# Threads
num.network.threads=3
num.io.threads=8
num.replica.fetchers=3
num.recovery.threads.per.data.dir=1
# Socket
socket.send.buffer.bytes=102400
socket.receive.buffer.bytes=102400
socket.request.max.bytes=104857600
# Message
message.max.bytes=10485760
# Storage
log.dirs=/qaxdata/s/services/kafka/kafka_29092/data
# Topic defaults
num.partitions=32
default.replication.factor=1
offsets.topic.replication.factor=1
# Retention
offsets.retention.minutes=315360000
log.retention.hours=72
log.segment.bytes=1073741824
log.retention.check.interval.ms=300000
# Cleaner and deletion
log.cleaner.enable=true
delete.topic.enable=true
```
不再保留以下 2.2.1 参数:
```properties
broker.id
port
advertised.host.name
zookeeper.connect
zookeeper.connection.timeout.ms
controlled.shutdown.enable
security.inter.broker.protocol
authorizer.class.name=kafka.security.auth.SimpleAclAuthorizer
```
## 四、首次建立 3.9.1 KRaft 存储
仅首次从 ZooKeeper 配置转换为 KRaft 时执行。
### 1. 检查数据目录
```bash
ls -la /qaxdata/s/services/kafka/kafka_29092/data
```
检查是否已有:
```bash
cat /qaxdata/s/services/kafka/kafka_29092/data/meta.properties
```
如果这里包含旧集群数据,不能随意删除或覆盖 `meta.properties`。
### 2. 格式化 KRaft 存储
你已经使用的 Cluster ID:
```text
SV6NxEtETaO5x7G0wzq3NQ
```
执行:
```bash
cd /qaxdata/s/services/kafka/kafka_29092/kafka_2.12-3.9.1
bin/kafka-storage.sh format \
-t SV6NxEtETaO5x7G0wzq3NQ \
-c config/server.properties
```
这条命令整个集群生命周期只执行一次。
检查:
```bash
cat /qaxdata/s/services/kafka/kafka_29092/data/meta.properties
```
应包含:
```properties
cluster.id=SV6NxEtETaO5x7G0wzq3NQ
node.id=1
```
## 五、启动 Kafka 3.9.1
设置 JAAS:
```bash
cd /qaxdata/s/services/kafka/kafka_29092/kafka_2.12-3.9.1
export KAFKA_OPTS="-Djava.security.auth.login.config=$PWD/config/kafka_server_jaas.conf"
```
启动:
```bash
bin/kafka-server-start.sh \
-daemon config/server.properties
```
检查日志:
```bash
tail -n 200 logs/server.log
```
检查监听端口:
```bash
ss -lntp | grep -E ':29092|:29093'
```
检查 KRaft 状态:
```bash
bin/kafka-metadata-quorum.sh \
--bootstrap-controller private001v.tq.cztt.qianxin-inc.cn:29093 \
describe --status
```
检查 Feature:
```bash
bin/kafka-features.sh \
--bootstrap-controller private001v.tq.cztt.qianxin-inc.cn:29093 \
describe
```
3.9.1 阶段预期:
```text
kraft.version FinalizedVersionLevel: 0
metadata.version FinalizedVersionLevel: 3.9-IV0
```
## 六、准备 Kafka 4.3.1
Kafka 4.x 已经删除 Scala 2.12 发行包,因此使用:
```text
kafka_2.13-4.3.1
```
Kafka 4.3.1 服务端使用 Java 17 或更高版本:
```bash
java -version
```
建议明确设置:
```bash
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk
export PATH=$JAVA_HOME/bin:$PATH
```
### 1. 复制业务配置
```bash
cd /qaxdata/s/services/kafka/kafka_29092
cp kafka_2.12-3.9.1/config/server.properties \
kafka_2.13-4.3.1/config/server.properties
cp kafka_2.12-3.9.1/config/kafka_server_jaas.conf \
kafka_2.13-4.3.1/config/kafka_server_jaas.conf
```
不要复制整个 3.9 的 `config` 目录。
Kafka 4.3 使用 Log4j 2,必须保留 4.3.1 原始文件:
```text
config/log4j2.yaml
config/tools-log4j2.yaml
```
检查:
```bash
ls -l kafka_2.13-4.3.1/config/*log4j*
```
你之前出现的:
```text
Reconfiguration failed: No configuration found
```
就是命令行工具没有找到有效 Log4j2 配置,但不代表 KRaft 命令执行失败。
## 七、第一次使用 4.3.1 启动时保持静态仲裁
第一次从 3.9.1 启动 4.3.1 时,集群还是:
```text
kraft.version=0
```
因此先保留:
```properties
controller.quorum.voters=1@private001v.tq.cztt.qianxin-inc.cn:29093
```
这时 4.3.1 配置可以与你现在展示的配置一致。
### 1. 停止 3.9.1
```bash
cd /qaxdata/s/services/kafka/kafka_29092/kafka_2.12-3.9.1
bin/kafka-server-stop.sh
```
确认退出:
```bash
pgrep -af 'kafka.Kafka'
```
### 2. 启动 4.3.1
```bash
cd /qaxdata/s/services/kafka/kafka_29092/kafka_2.13-4.3.1
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk
export KAFKA_OPTS="-Djava.security.auth.login.config=$PWD/config/kafka_server_jaas.conf"
bin/kafka-server-start.sh \
-daemon config/server.properties
```
从 3.9 升级到 4.3 时绝对不要执行:
```bash
bin/kafka-storage.sh format
```
4.3.1 直接读取 3.9.1 已经格式化的原数据目录:
```properties
log.dirs=/qaxdata/s/services/kafka/kafka_29092/data
```
## 八、验证 4.3.1 程序升级
确认程序版本:
```bash
bin/kafka-topics.sh --version
```
检查日志:
```bash
tail -n 200 logs/server.log
```
检查 KRaft:
```bash
bin/kafka-metadata-quorum.sh \
--bootstrap-controller private001v.tq.cztt.qianxin-inc.cn:29093 \
describe --status
```
检查 Feature:
```bash
bin/kafka-features.sh \
--bootstrap-controller private001v.tq.cztt.qianxin-inc.cn:29093 \
describe
```
刚启动 4.3.1 但尚未提升 Feature 时,应类似:
```text
metadata.version:
SupportedMaxVersion: 4.3-IV0
FinalizedVersionLevel: 3.9-IV0
kraft.version:
FinalizedVersionLevel: 0
```
这时完成的是"程序升级",尚未最终升级集群元数据。
## 九、升级 metadata.version
建议逐级确认,而不是启动 4.3 后立即全部提升。
### 1. 先最终升级到 4.0
```bash
bin/kafka-features.sh \
--bootstrap-controller private001v.tq.cztt.qianxin-inc.cn:29093 \
upgrade \
--release-version 4.0
```
检查:
```bash
bin/kafka-features.sh \
--bootstrap-controller private001v.tq.cztt.qianxin-inc.cn:29093 \
describe
```
你现在已经达到:
```text
metadata.version FinalizedVersionLevel: 4.0-IV3
```
### 2. 升级 KRaft 动态仲裁功能
如果尚未升级:
```bash
bin/kafka-features.sh \
--bootstrap-controller private001v.tq.cztt.qianxin-inc.cn:29093 \
upgrade \
--feature kraft.version=1
```
你当前已经是:
```text
kraft.version FinalizedVersionLevel: 1
```
因此这一步不用重复执行。
## 十、当前必须修改 4.3.1 配置
由于你的集群已经是:
```text
kraft.version=1
```
按照 Kafka 4.3 规则,应从静态仲裁配置:
```properties
controller.quorum.voters=1@private001v.tq.cztt.qianxin-inc.cn:29093
```
改成动态仲裁引导地址:
```properties
controller.quorum.bootstrap.servers=private001v.tq.cztt.qianxin-inc.cn:29093
```
修改:
```bash
vi /qaxdata/s/services/kafka/kafka_29092/kafka_2.13-4.3.1/config/server.properties
```
删除:
```properties
controller.quorum.voters=1@private001v.tq.cztt.qianxin-inc.cn:29093
```
增加:
```properties
controller.quorum.bootstrap.servers=private001v.tq.cztt.qianxin-inc.cn:29093
```
检查:
```bash
grep -E \
'^(controller.quorum.voters|controller.quorum.bootstrap.servers)=' \
/qaxdata/s/services/kafka/kafka_29092/kafka_2.13-4.3.1/config/server.properties
```
只能输出:
```text
controller.quorum.bootstrap.servers=private001v.tq.cztt.qianxin-inc.cn:29093
```
Kafka 官方明确要求:`kraft.version=1` 生效后,删除 `controller.quorum.voters` 并配置 `controller.quorum.bootstrap.servers`。[Kafka 4.3 KRaft 升级说明](https://kafka.apache.org/43/operations/kraft/)
## 十一、Kafka 4.3.1 最终配置
```properties
node.id=1
process.roles=broker,controller
controller.quorum.bootstrap.servers=private001v.tq.cztt.qianxin-inc.cn:29093
controller.listener.names=CONTROLLER
listener.security.protocol.map=CONTROLLER:PLAINTEXT,SASL_PLAINTEXT:SASL_PLAINTEXT
listeners=SASL_PLAINTEXT://0.0.0.0:29092,CONTROLLER://0.0.0.0:29093
advertised.listeners=SASL_PLAINTEXT://private001v.tq.cztt.qianxin-inc.cn:29092
inter.broker.listener.name=SASL_PLAINTEXT
sasl.enabled.mechanisms=PLAIN
sasl.mechanism.inter.broker.protocol=PLAIN
authorizer.class.name=org.apache.kafka.metadata.authorizer.StandardAuthorizer
allow.everyone.if.no.acl.found=true
num.network.threads=3
num.io.threads=8
num.replica.fetchers=3
num.recovery.threads.per.data.dir=1
socket.send.buffer.bytes=102400
socket.receive.buffer.bytes=102400
socket.request.max.bytes=104857600
message.max.bytes=10485760
log.dirs=/qaxdata/s/services/kafka/kafka_29092/data
num.partitions=32
default.replication.factor=1
offsets.topic.replication.factor=1
offsets.retention.minutes=315360000
log.retention.hours=72
log.segment.bytes=1073741824
log.retention.check.interval.ms=300000
log.cleaner.enable=true
delete.topic.enable=true
```
修改完成后正常重启 4.3.1 并验证:
```bash
bin/kafka-server-stop.sh
```
```bash
bin/kafka-server-start.sh \
-daemon config/server.properties
```
```bash
bin/kafka-metadata-quorum.sh \
--bootstrap-controller private001v.tq.cztt.qianxin-inc.cn:29093 \
describe --status
```
## 十二、是否继续升级到 metadata.version 4.3
你现在是:
```text
Kafka程序:4.3.1
metadata.version:4.0-IV3
kraft.version:1
```
这个状态可以正常运行。
生产、消费、事务、ACL 及消费组都验证正常后,如需正式启用 4.3 元数据能力,再执行:
```bash
bin/kafka-features.sh \
--bootstrap-controller private001v.tq.cztt.qianxin-inc.cn:29093 \
upgrade \
--release-version 4.3
```
检查:
```bash
bin/kafka-features.sh \
--bootstrap-controller private001v.tq.cztt.qianxin-inc.cn:29093 \
describe
```
预期:
```text
metadata.version FinalizedVersionLevel: 4.3-IV0
```
这一步不可依赖降级恢复,执行前必须完成备份和业务验证。[Kafka 4.3.1 升级指南](https://kafka.apache.org/43/getting-started/upgrade/)
最终过程可以压缩为:
```text
停止2.2.1
→ 备份Kafka数据和ZooKeeper
→ 转换3.9.1 KRaft配置
→ 仅首次执行storage format
→ 启动并验证3.9.1
→ 停止3.9.1
→ 使用同一数据目录启动4.3.1
→ 不再format
→ 验证业务
→ 提升metadata.version
→ 提升kraft.version=1
→ voters改为bootstrap.servers
→ 重启验证
→ 最后按需提升metadata.version到4.3
```