3. Kafka 集群搭建:单机与集群模式部署、ZooKeeper/KRaft 配置、启动与验证
Kafka 的部署模式直接决定了系统的可用性、扩展性与运维复杂度。本章将系统讲解单机模式与集群模式的区别,并对比传统的 ZooKeeper 架构与新一代 KRaft 架构的配置要点,最后通过启动验证步骤确保集群正常运行。
3.1 部署模式对比
在开始搭建之前,需要明确单机与集群模式的核心差异,以便根据实际场景选择合适的部署方案。
| 对比维度 | 单机模式 | 集群模式 |
|---|---|---|
| 适用场景 | 开发测试、学习验证 | 生产环境、高可用要求 |
| 节点数量 | 1 个 Broker | ≥3 个 Broker |
| 数据冗余 | 无副本,数据丢失风险高 | 多副本(replication-factor ≥ 2) |
| 故障恢复 | 服务中断,需手动恢复 | 自动 Leader 选举,服务不中断 |
| 元数据管理 | ZooKeeper 或 KRaft 单节点 | ZooKeeper 集群或 KRaft 仲裁 |
建议: 即使是学习环境,也推荐使用 3 节点集群模式,以便体验分区副本、Leader 选举等核心特性。
3.2 架构选择:ZooKeeper vs KRaft
Kafka 2.8 开始引入 KRaft 模式,旨在去除对 ZooKeeper 的依赖。Kafka 3.x 版本中两种模式并存,但 KRaft 将成为未来主流。
- ZooKeeper 模式:元数据(Broker 注册、Topic 分区、Controller 选举)由 ZooKeeper 集群管理,Kafka Broker 只负责消息存储与流转。
- KRaft 模式:元数据由 Kafka 自身基于 Raft 共识算法管理,无需额外部署 ZooKeeper,运维更简单。
以下 SVG 图展示了两种架构的核心组件与交互关系:
3.3 单机模式部署(ZooKeeper 版)
单机模式适合快速验证,以下步骤基于 Kafka 3.5 版本,使用 ZooKeeper 管理元数据。
3.3.1 下载与解压
wget https://downloads.apache.org/kafka/3.5.0/kafka_2.13-3.5.0.tgz
tar -xzf kafka_2.13-3.5.0.tgz
cd kafka_2.13-3.5.0
3.3.2 启动 ZooKeeper
# 使用 Kafka 自带的 ZooKeeper 启动脚本
bin/zookeeper-server-start.sh config/zookeeper.properties
3.3.3 启动 Kafka Broker
# 修改 config/server.properties 中的 listeners 和 advertised.listeners
# listeners=PLAINTEXT://localhost:9092
# advertised.listeners=PLAINTEXT://localhost:9092
bin/kafka-server-start.sh config/server.properties
3.3.4 验证单机模式
# 创建测试 Topic
bin/kafka-topics.sh --create --topic test-topic --bootstrap-server localhost:9092 --partitions 1 --replication-factor 1
# 查看 Topic 列表
bin/kafka-topics.sh --list --bootstrap-server localhost:9092
# 发送消息
echo "Hello Kafka" | bin/kafka-console-producer.sh --topic test-topic --bootstrap-server localhost:9092
# 消费消息
bin/kafka-console-consumer.sh --topic test-topic --from-beginning --bootstrap-server localhost:9092
注意: 单机模式下 replication-factor 只能设为 1,因为只有一个 Broker 节点,无法创建副本。
3.4 集群模式部署(ZooKeeper 版)
生产环境推荐至少 3 个 Broker 节点,配合 3 或 5 个 ZooKeeper 节点。以下以 3 节点集群为例。
3.4.1 节点规划
| 节点角色 | 主机名 | IP 地址 | 端口 |
|---|---|---|---|
| ZooKeeper 1 | zk1 | 192.168.1.101 | 2181 |
| ZooKeeper 2 | zk2 | 192.168.1.102 | 2181 |
| ZooKeeper 3 | zk3 | 192.168.1.103 | 2181 |
| Kafka Broker 1 | kafka1 | 192.168.1.201 | 9092 |
| Kafka Broker 2 | kafka2 | 192.168.1.202 | 9092 |
| Kafka Broker 3 | kafka3 | 192.168.1.203 | 9092 |
3.4.2 ZooKeeper 集群配置
在每个 ZooKeeper 节点的 zookeeper.properties 中添加以下配置:
dataDir=/data/zookeeper
clientPort=2181
maxClientCnxns=60
tickTime=2000
initLimit=10
syncLimit=5
server.1=192.168.1.101:2888:3888
server.2=192.168.1.102:2888:3888
server.3=192.168.1.103:2888:3888
在 dataDir 目录下创建 myid 文件,内容为对应节点的编号(1、2、3)。
3.4.3 Kafka Broker 集群配置
每个 Broker 的 server.properties 核心配置如下:
# Broker 唯一 ID,每个节点不同
broker.id=1
# 监听地址
listeners=PLAINTEXT://192.168.1.201:9092
advertised.listeners=PLAINTEXT://192.168.1.201:9092
# 日志存储目录
log.dirs=/data/kafka/logs
# ZooKeeper 连接串
zookeeper.connect=192.168.1.101:2181,192.168.1.102:2181,192.168.1.103:2181
# 副本相关
num.partitions=3
default.replication.factor=2
min.insync.replicas=1
3.4.4 启动顺序
- 依次启动所有 ZooKeeper 节点:
bin/zookeeper-server-start.sh config/zookeeper.properties - 依次启动所有 Kafka Broker:
bin/kafka-server-start.sh config/server.properties
3.5 KRaft 模式集群部署
KRaft 模式无需 ZooKeeper,元数据由 Controller 仲裁管理。以下配置基于 Kafka 3.5 版本。
3.5.1 生成集群 ID
bin/kafka-storage.sh random-uuid
# 输出示例:MkU3OEVBNTcwNTJENDM2Qk
3.5.2 配置 Controller 节点
创建 config/kraft/controller.properties:
process.roles=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
listeners=CONTROLLER://192.168.1.101:9093
advertised.listeners=CONTROLLER://192.168.1.101:9093
log.dirs=/data/kraft/controller-logs
3.5.3 配置 Broker 节点
创建 config/kraft/broker.properties:
process.roles=broker
node.id=4
controller.quorum.voters=1@192.168.1.101:9093,2@192.168.1.102:9093,3@192.168.1.103:9093
listeners=PLAINTEXT://192.168.1.201:9092
advertised.listeners=PLAINTEXT://192.168.1.201:9092
log.dirs=/data/kraft/broker-logs
3.5.4 格式化存储目录
# 所有节点都需要执行,使用相同的集群 ID
bin/kafka-storage.sh format -t <集群ID> -c config/kraft/controller.properties
bin/kafka-storage.sh format -t <集群ID> -c config/kraft/broker.properties
3.5.5 启动 KRaft 集群
# 先启动 Controller 节点
bin/kafka-server-start.sh config/kraft/controller.properties
# 再启动 Broker 节点
bin/kafka-server-start.sh config/kraft/broker.properties
重要: KRaft 模式下,Controller 节点数量必须为奇数(1、3、5…),以保证 Raft 仲裁能够选出 Leader。Broker 节点数量无此限制。
3.6 集群验证
无论使用哪种模式,启动完成后都需要验证集群是否正常工作。
3.6.1 验证 Broker 注册
# 查看所有 Broker 是否已注册
bin/kafka-broker-api-versions.sh --bootstrap-server 192.168.1.201:9092
# 查看集群描述
bin/kafka-cluster.sh --bootstrap-server 192.168.1.201:9092 describe
3.6.2 创建带副本的 Topic
# 创建 3 分区、2 副本的 Topic
bin/kafka-topics.sh --create --topic cluster-test \
--bootstrap-server 192.168.1.201:9092 \
--partitions 3 --replication-factor 2
# 查看 Topic 详情,确认副本分布
bin/kafka-topics.sh --describe --topic cluster-test \
--bootstrap-server 192.168.1.201:9092
3.6.3 故障转移测试
# 手动停止一个 Broker
bin/kafka-server-stop.sh
# 查看 Topic 分区 Leader 是否重新选举
bin/kafka-topics.sh --describe --topic cluster-test \
--bootstrap-server 192.168.1.202:9092
# 重新启动该 Broker,观察是否重新同步
bin/kafka-server-start.sh config/server.properties
以下 SVG 图展示了集群模式下分区副本的分布与故障转移流程:
3.7 常见问题与排查
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| Broker 启动后立即退出 | 端口被占用、日志目录权限不足 | 检查端口占用,确保 log.dirs 目录可写 |
Topic 创建失败:LEADER_NOT_AVAILABLE |
副本数超过 Broker 数量 | 确保 replication-factor ≤ Broker 数量 |
| 消费者无法连接 | advertised.listeners 配置错误 |
设置为客户端可访问的 IP 或主机名 |
| KRaft 模式下 Controller 无法选举 | 节点 ID 重复或仲裁配置错误 | 检查 node.id 唯一性,确认 controller.quorum.voters 格式正确 |
最佳实践: 生产环境建议使用 KRaft 模式,减少运维组件;如果仍使用 ZooKeeper 模式,务必为 ZooKeeper 集群配置独立的监控告警。