Kafka 2.x vs 3.x,我为什么选择升级?
这是一个小白的学习记录
边学边练,把踩过的坑都记下来
先说下我为什么要学这个
公司项目要用 Kafka,让我负责调研。拿到手一看,好家伙,2.x 和 3.x 到底选哪个?
网上的文档要么太深奥,要么太简单。没办法,只能自己一点点啃,顺便把学习笔记整理出来。
如果你也是新手,希望这篇笔记能帮到你。
我的基础
- Java 能看懂(CRUD 工程师)
- Linux 命令会用(cd、ls、vim 三件套)
- 消息队列知道个大概(RabbitMQ 用过)
我的学习方法
- 先搭环境:2.x 和 3.x 各装一套(装了好几次才成功)
- 边看边试:看到什么配置,立马试试
- 记笔记:好记性不如烂笔头
- 不怕错:反正是测试环境,随便折腾
Kafka 版本,到底怎么选?
先放张图:
2018-11 Kafka 2.0 2019-04 Kafka 2.2 很多公司还在用 2020-07 Kafka 2.6 2021-11 Kafka 3.0 大更新 2022-06 Kafka 3.2 2023-10 Kafka 3.6 我学的是这个 Kafka 版本发展
说实话,这么多版本,我当时也懵。后来问了大佬,总结就一句话:
老项目用 2.x 就别动了,新项目直接上 3.x
2.x 和 3.x,最大的区别是啥?
先看张架构图:
3.x - 不需要 ZooKeeper
生产者
Controller 集群 🎉
Broker 节点
消费者
2.x - 需要 ZooKeeper
生产者
ZooKeeper 🐘
Controller
其他 Broker
消费者
看懂了吗?看不懂没事,我当时也看不懂。
说人话就是:
- 2.x:需要额外装个 ZooKeeper(就像买个手机还得配个充电器)
- 3.x:自己就能搞定(手机自带无线充电)
我学到的 5 个关键点
1. 不用装 ZooKeeper 了
2.x 配置:
yaml
# 我当时看到这个都懵了
zookeeper.connect: zk1:2181,zk2:2181,zk3:2181/kafka
zookeeper.connection.timeout.ms: 18000
zookeeper.session.timeout.ms: 18000
3.x 配置:
yaml
# 简单多了
process.roles: broker,controller
node.id: 1
controller.quorum.voters: 1@localhost:9093,2@localhost:9094,3@localhost:9095
我的感受:
- 少装一个软件,省事了
- 配置也少了,不容易出错
- 最重要的是:少一个要维护的东西
2. Controller 选举快了很多
这个说实话我不太懂原理,但知道结果很重要。
2.x 的问题:
选举一次要 10-30 秒,这段时间 Kafka 不能正常工作。
3.x 的改进:
毫秒级完成,几乎感觉不到。
为什么重要?
我之前实习的时候,公司 Kafka 出过问题,Controller 选举花了半分钟,整个系统都卡了。老板在旁边看着,急得我满头汗...
所以这个改进真的很实用。
3. 性能怎么样?
说实话,这个我测试不出来,公司也没让我测。
看了一些测试报告,大概是这样:
吞吐量对比(大概这样) 2.x 3.x 120 110 100 90 80 70 60 50 40 30 20 10 0 相对性能
我的理解:
- 吞吐量差不多,甚至 3.x 还略低一点
- 但这不重要,谁没事天天盯着吞吐量
- 关键是运维简单了,出了问题好排查
4. 消费者重平衡
这个我实际遇到过。
2.x 的问题:
消费者组重平衡的时候,所有消费者都停了。就像排队结账,收银员突然说"我要盘点",所有人都得等着。
3.x 的改进:
只影响变化的部分,其他人继续。
实际体验:
之前用 2.x,每次重启一个消费者,整个组都卡一下。现在用 3.x,基本感觉不到。
5. 存储空间
这个我实测过!
2.x 配置:
yaml
log.segment.bytes: 1073741824 # 1GB
log.cleaner.enable: false # 不压缩
3.x 配置:
yaml
log.segment.bytes: 536870912 # 512MB
log.cleaner.enable: true # 启用压缩
我的测试结果:
同样的数据量,3.x 大概省了 30% 左右的空间。文本数据更省,二进制数据少一点。
代码层面,有啥不一样?
Controller 选举
这个我看了源码(其实也没看懂多少):
2.x 流程:
1. 在 ZooKeeper 创建节点
2. 等 ZooKeeper 通知
3. 同步元数据(要很多次网络请求)
3.x 流程:
1. 发送投票请求
2. 多数同意就当选
3. 一次复制完成
为什么快?
简单说就是:3.x 不依赖外部系统,自己搞定。
我实际升级踩的坑
坑 1:配置没改对
yaml
# ❌ 我当时这么配,启动失败
zookeeper.connect: localhost:2181 # KRaft 模式不需要这个!
# ✅ 应该这么配
process.roles: broker,controller
教训:KRaft 模式下,别配 ZooKeeper!
坑 2:一起重启所有 Broker
bash
# ❌ 我当时手贱,一起重启了
kill -9 <pid1>
kill -9 <pid2>
kill -9 <pid3>
# 结果:集群挂了,重启了好久
# ✅ 正确做法:一个一个来
kill -9 <pid1>
# 等 1 分钟,确认正常
kill -9 <pid2>
教训:别手贱!一个一个重启!
坑 3:没监控就升级
bash
# ❌ 我当时头铁,直接升级
# 结果:出问题了不知道哪的问题
# ✅ 正确做法:先配监控
# - CPU 使用率
# - 内存使用率
# - 磁盘 IO
# - 网络流量
教训:监控很重要!很重要!很重要!
升级步骤(我亲测可用)
第一步:检查
bash
# 看看当前版本
kafka-topics.sh --bootstrap-server localhost:9092 --describe
# 看看有哪些消费者
kafka-consumer-groups.sh --bootstrap-server localhost:9092 --list
# 备份!备份!备份!
cp server.properties server.properties.bak
第二步:滚动升级
yaml
# 先升级一个 Broker
inter.broker.protocol.version=2.8
log.message.format.version=2.8
# 观察 1 小时,没问题再继续
# 所有 Broker 升级后
inter.broker.protocol.version=3.0
log.message.format.version=3.0
# 重启(一个一个来)
第三步:切 KRaft(可选)
bash
# 生成集群 ID
kafka-storage.sh random-uuid
# 格式化
kafka-storage.sh format -t <uuid> -c kraft.properties
# 启动
kafka-server-start.sh kraft.properties
我的建议:
这步在测试环境先试试,生产环境谨慎。
我整理的一些配置
3.x 推荐配置
yaml
# 这些是我实测好用的
batch.size: 32768 # 32KB
linger.ms: 5 # 等 5ms
compression.type: zstd # 压缩
session.timeout.ms: 45000 # 45 秒
监控指标
yaml
# 2.x 的
kafka.controller:type=KafkaController,name=ActiveControllerCount
# 3.x 新增的(要加到监控里)
kafka.controller:type=RaftMetrics,name=CurrentLeader
kafka.controller:type=RaftMetrics,name=State
最后说两句
写这篇笔记的时候,我也是刚入门不久。肯定有理解不对的地方,欢迎大佬指正。