2. Kafka集群搭建:单机与集群部署、ZooKeeper/KRaft模式、配置文件详解
搭建Kafka集群,是咱们进入流式数据清洗的第一道门槛。说实话,很多初学者在这步就被劝退了——不是技术多难,而是版本选型、模式切换这些坑太多。我当年第一次搭集群时,光ZooKeeper和Kafka的版本兼容问题就折腾了一下午。
这一章,咱们把集群搭建这件事彻底讲透。从单机到集群,从ZooKeeper模式到KRaft模式,每个配置文件参数我都会告诉你哪些是坑、哪些是宝。
核心要点:Kafka 2.8+开始支持KRaft模式(去ZooKeeper),但生产环境建议3.0+再用。我个人习惯:测试环境用KRaft,生产环境如果团队熟悉ZooKeeper,可以继续用ZK模式过渡。
2.1 单机部署:先跑起来再说
单机部署是最简单的入门方式。说白了,就是让你先感受一下Kafka到底怎么玩。
2.1.1 环境准备
- JDK 11+(Kafka 3.x强制要求,我之前用JDK8踩过坑)
- 下载Kafka二进制包(建议用官方镜像,别用第三方编译版)
- 一台Linux/Mac机器(Windows也能跑,但生产环境别这么干)
2.1.2 启动ZooKeeper(传统模式)
Kafka依赖ZooKeeper管理元数据。先启动ZK:
# 解压Kafka包
tar -xzf kafka_2.13-3.4.0.tgz
cd kafka_2.13-3.4.0
# 启动ZooKeeper(Kafka内置了ZK脚本)
bin/zookeeper-server-start.sh config/zookeeper.properties
这里要注意:zookeeper.properties里的dataDir路径,默认在/tmp下。生产环境一定要改!我见过有人上线忘了改,重启后数据全丢——那场面,啧啧。
2.1.3 启动Kafka Broker
# 修改config/server.properties
# 关键参数:
broker.id=0
listeners=PLAINTEXT://localhost:9092
log.dirs=/data/kafka/logs # 别用/tmp!
# 启动Kafka
bin/kafka-server-start.sh config/server.properties
小技巧:启动时加-daemon参数可以让进程后台运行:bin/kafka-server-start.sh -daemon config/server.properties。这样你就不用一直开着终端了。
2.2 集群部署:从单机到多节点
单机只是玩具,集群才是生产。集群部署的核心就三件事:Broker ID唯一、日志目录独立、所有节点能互相通信。
2.2.1 集群规划
假设我们搭一个3节点集群:
| 节点 | IP | Broker ID | 端口 |
|---|---|---|---|
| kafka-1 | 192.168.1.101 | 0 | 9092 |
| kafka-2 | 192.168.1.102 | 1 | 9092 |
| kafka-3 | 192.168.1.103 | 2 | 9092 |
2.2.2 配置文件差异
每个节点的server.properties只有几个参数不同:
# kafka-1 的配置
broker.id=0
listeners=PLAINTEXT://192.168.1.101:9092
advertised.listeners=PLAINTEXT://192.168.1.101:9092
# kafka-2 的配置
broker.id=1
listeners=PLAINTEXT://192.168.1.102:9092
advertised.listeners=PLAINTEXT://192.168.1.102:9092
# kafka-3 的配置
broker.id=2
listeners=PLAINTEXT://192.168.1.103:9092
advertised.listeners=PLAINTEXT://192.168.1.103:9092
注意:advertised.listeners这个参数特别容易忘。它是告诉客户端「你应该连哪个地址」。如果内外网地址不一致(比如云服务器),这个参数必须配对。我曾经因为没配这个,客户端一直连不上——折腾了两小时才发现。
2.2.3 启动集群
先在所有节点启动ZooKeeper(或者用独立的ZK集群),然后依次启动Kafka:
# 在每个节点上执行
bin/kafka-server-start.sh -daemon config/server.properties
# 验证集群状态
bin/kafka-broker-api-versions.sh --bootstrap-server 192.168.1.101:9092
如果看到三个Broker都返回了版本信息,恭喜你,集群搭好了。
2.3 ZooKeeper vs KRaft:模式选择
这是Kafka 2.8之后最大的变化。KRaft模式去掉了ZooKeeper依赖,用Kafka自己的Raft协议管理元数据。
2.3.1 两种模式对比
| 特性 | ZooKeeper模式 | KRaft模式 |
|---|---|---|
| 元数据存储 | ZooKeeper集群 | Kafka自身 |
| 组件数量 | Kafka + ZK(至少2套系统) | 只有Kafka |
| 运维复杂度 | 高(ZK也要维护) | 低(单一系统) |
| 成熟度 | 非常成熟(生产首选) | 3.0+开始稳定 |
| 控制器选举 | 依赖ZK | Raft协议自选举 |
2.3.2 KRaft模式配置
KRaft模式需要先生成集群ID,然后配置controller.quorum.voters:
# 1. 生成集群ID
bin/kafka-storage.sh random-uuid
# 输出:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
# 2. 格式化存储目录
bin/kafka-storage.sh format -t <集群ID> -c config/kraft/server.properties
# 3. 修改server.properties
process.roles=broker,controller
node.id=1
controller.quorum.voters=1@192.168.1.101:9093,2@192.168.1.102:9093,3@192.168.1.103:9093
# 4. 启动
bin/kafka-server-start.sh config/kraft/server.properties
我的建议:如果你是新项目,直接用KRaft模式。少维护一套ZooKeeper,省心不少。但如果是已有ZK集群的老项目,别急着迁移——等Kafka 3.5+再考虑,那时候KRaft会更成熟。
2.4 配置文件详解:每个参数都是坑
Kafka的配置文件有上百个参数,但真正关键的也就十几个。我按重要程度给你排个序:
2.4.1 必配参数
| 参数 | 默认值 | 说明 | 避坑指南 |
|---|---|---|---|
broker.id |
0 | 集群内唯一标识 | 不能重复,否则启动报错 |
listeners |
PLAINTEXT://:9092 | 监听地址 | 生产环境用内网IP,别用0.0.0.0 |
log.dirs |
/tmp/kafka-logs | 数据存储目录 | 必须改!/tmp重启就丢数据 |
zookeeper.connect |
localhost:2181 | ZK连接地址 | 集群模式用逗号分隔多个ZK |
2.4.2 性能调优参数
这些参数直接影响吞吐量和延迟:
# 网络线程数(一般设为CPU核数)
num.network.threads=8
# IO线程数(建议CPU核数*2)
num.io.threads=16
# 每个分区日志段大小(默认1GB)
log.segment.bytes=1073741824
# 日志保留时间(默认7天)
log.retention.hours=168
# 批量消息最大大小(默认1MB)
max.message.bytes=1048576
重要:log.retention.hours和log.retention.bytes是「或」关系——只要满足一个条件就清理。我见过有人只配了时间没配大小,结果磁盘写满了才报警。建议两个都配,比如保留7天或50GB。
2.4.3 副本与容错参数
| 参数 | 默认值 | 说明 |
|---|---|---|
default.replication.factor |
1 | 默认副本数,生产建议3 |
min.insync.replicas |
1 | 最小同步副本数,建议设为2 |
unclean.leader.election.enable |
false | 是否允许非ISR副本成为Leader |
这里有个经典组合:replication.factor=3 + min.insync.replicas=2 + acks=all。这样配置后,即使一台Broker挂了,数据也不会丢。我在金融项目里就是这么配的——数据一致性比性能重要。
2.5 集群架构总览
下面这张图展示了Kafka集群的核心组件和交互关系:
2.6 验证集群:确认一切正常
集群搭好了,怎么确认它真的在工作?我一般用这几个命令:
# 1. 查看Broker列表
bin/kafka-broker-api-versions.sh --bootstrap-server localhost:9092
# 2. 创建测试Topic
bin/kafka-topics.sh --create --topic test-topic \
--bootstrap-server localhost:9092 \
--partitions 3 --replication-factor 2
# 3. 查看Topic详情
bin/kafka-topics.sh --describe --topic test-topic \
--bootstrap-server localhost:9092
# 4. 生产消费测试
# 终端1:启动生产者
bin/kafka-console-producer.sh --topic test-topic \
--bootstrap-server localhost:9092
# 终端2:启动消费者
bin/kafka-console-consumer.sh --topic test-topic \
--bootstrap-server localhost:9092 \
--from-beginning
如果生产者输入的消息能在消费者端看到,说明集群一切正常。嗯,到这里,你的Kafka集群就算正式上线了。
总结一下:单机部署是入门,集群部署是基本功,ZooKeeper和KRaft是两种选择,配置文件是日常运维的核心。把这些搞明白,后面做流式数据清洗时,你就能把精力放在业务逻辑上,而不是被基础设施折腾。