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集群的核心组件和交互关系:

Kafka集群架构图 Kafka集群核心架构 生产者 消费者 Broker 1 Leader: P0, P3 Broker 2 Leader: P1, P4 Broker 3 Leader: P2, P5 ZooKeeper / KRaft 说明:生产者将消息发送到Broker集群,Broker之间通过副本机制同步数据,元数据由ZooKeeper或KRaft管理

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是两种选择,配置文件是日常运维的核心。把这些搞明白,后面做流式数据清洗时,你就能把精力放在业务逻辑上,而不是被基础设施折腾。