2. Kafka集群部署:ZooKeeper/KRaft模式对比、集群规划、配置文件详解、启动与验证
2.1 共识机制演进:ZooKeeper vs KRaft
Kafka 从 2.8 版本开始引入基于 Raft 协议的 KRaft 模式,逐步摆脱对 ZooKeeper 的外部依赖。两种模式在架构复杂度、部署运维、故障恢复等方面存在显著差异。
| 对比维度 | ZooKeeper 模式 | KRaft 模式 |
|---|---|---|
| 依赖组件 | Kafka Broker + 独立 ZooKeeper 集群(≥3节点) | 仅 Kafka Broker,元数据由 Controller 节点管理 |
| 元数据存储 | ZooKeeper 树形节点(/brokers, /controller, /admin 等) | 内部 KRaft 日志(__cluster_metadata 主题) |
| Controller 选举 | 基于 ZooKeeper 临时节点 + Watcher 机制 | 基于 Raft 协议投票选举,Leader/Follower 角色 |
| 节点角色 | 所有 Broker 对等,Controller 为动态选举角色 | 静态角色:Controller(Quorum 节点)与 Broker(数据节点) |
| 部署规模 | 至少 3 ZooKeeper + 3 Broker = 6 进程 | 至少 3 Controller + 2 Broker = 5 进程(生产推荐) |
| 运维复杂度 | 高:需独立维护 ZK 集群、处理 ZK 脑裂、版本兼容 | 低:单进程管理,无外部依赖 |
| 成熟度 | 生产级,社区长期验证 | 3.3+ 版本生产可用,3.5+ 版本推荐生产 |
选型建议: 新建集群优先选择 KRaft 模式(Kafka ≥ 3.5),可降低 40% 以上的运维成本。存量 ZooKeeper 模式集群建议通过滚动升级逐步迁移,避免大版本跳跃。
2.2 集群规划与节点角色分配
KRaft 模式下,节点分为 Controller(Quorum) 和 Broker 两类角色。Controller 负责元数据管理与 Raft 共识,Broker 负责数据读写与分区复制。
生产环境推荐规划(6节点示例):
Controller 节点 × 3:node-1, node-2, node-3(仅运行 Controller 进程)
Broker 节点 × 3:node-4, node-5, node-6(仅运行 Broker 进程)
Controller 数量必须为奇数(1/3/5),推荐 3 或 5。
Controller 节点 × 3:node-1, node-2, node-3(仅运行 Controller 进程)
Broker 节点 × 3:node-4, node-5, node-6(仅运行 Broker 进程)
Controller 数量必须为奇数(1/3/5),推荐 3 或 5。
2.3 配置文件详解
2.3.1 KRaft 模式核心配置(controller.properties)
# 节点角色:controller 或 broker
process.roles=controller
# 节点 ID,集群内唯一
node.id=1
# Quorum 投票节点列表,格式:nodeId@host:port
controller.quorum.voters=1@192.168.1.10:9093,2@192.168.1.11:9093,3@192.168.1.12:9093
# 监听地址与端口
listeners=CONTROLLER://0.0.0.0:9093
# 安全协议映射
listener.security.protocol.map=CONTROLLER:PLAINTEXT
# 日志目录(元数据日志)
log.dirs=/data/kraft-controller-logs
# 初始集群 ID(首次启动前需生成)
# 生成命令:./bin/kafka-storage.sh random-uuid
2.3.2 Broker 核心配置(server.properties)
# 节点角色
process.roles=broker
# 节点 ID,与 controller 节点 ID 不冲突
node.id=4
# 指向 Controller 集群
controller.quorum.voters=1@192.168.1.10:9093,2@192.168.1.11:9093,3@192.168.1.12:9093
# 数据监听地址(客户端访问)
listeners=PLAINTEXT://0.0.0.0:9092
# 对外暴露地址(需与客户端网络可达)
advertised.listeners=PLAINTEXT://192.168.1.13:9092
# 数据日志目录
log.dirs=/data/kafka-logs
# 分区默认副本数
default.replication.factor=3
# 最小 ISR 副本数
min.insync.replicas=2
# 日志保留策略(7天)
log.retention.hours=168
# 日志段大小(1GB)
log.segment.bytes=1073741824
关键注意事项:
1.
2.
3.
4. 首次启动前必须执行
1.
process.roles 必须明确指定,不可同时设置为 controller 和 broker(除非单节点测试)。2.
controller.quorum.voters 在所有节点上必须完全一致,否则 Raft 选举失败。3.
node.id 在集群内全局唯一,Controller 与 Broker 共用 ID 空间。4. 首次启动前必须执行
kafka-storage.sh format 格式化元数据日志。
2.4 集群启动与验证
2.4.1 启动步骤
- 生成集群 ID(仅首次):
# 在任意一台节点执行
./bin/kafka-storage.sh random-uuid
# 输出示例:MkU3OEVBNTcwNTJENDM2Qk
- 格式化元数据日志(每台 Controller 节点执行):
./bin/kafka-storage.sh format -t MkU3OEVBNTcwNTJENDM2Qk -c config/kraft/controller.properties
# 输出:Formatting /data/kraft-controller-logs with metadata uuid MkU3OEVBNTcwNTJENDM2Qk
- 启动 Controller 节点(按顺序启动 3 台):
./bin/kafka-server-start.sh -daemon config/kraft/controller.properties
# 检查进程
jps | grep Kafka
# 查看日志
tail -f logs/controller.log | grep "transition to leader"
- 启动 Broker 节点(启动所有 Broker):
./bin/kafka-server-start.sh -daemon config/kraft/server.properties
# 检查进程
jps | grep Kafka
# 查看日志
tail -f logs/server.log | grep "registered broker"
2.4.2 集群验证命令
| 验证项 | 命令 | 预期输出 |
|---|---|---|
| 查看 Broker 列表 | ./bin/kafka-broker-api-versions.sh --bootstrap-server localhost:9092 |
返回各 Broker 支持的 API 版本列表 |
| 查看 Controller 信息 | ./bin/kafka-metadata-quorum.sh --bootstrap-server localhost:9092 describe --status |
显示 Leader ID、Voter 列表、日志偏移 |
| 创建测试主题 | ./bin/kafka-topics.sh --create --topic test-topic --partitions 3 --replication-factor 3 --bootstrap-server localhost:9092 |
Created topic test-topic |
| 查看主题详情 | ./bin/kafka-topics.sh --describe --topic test-topic --bootstrap-server localhost:9092 |
显示分区 Leader、Replicas、ISR 分布 |
| 生产消息测试 | echo "hello" | ./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 |
输出 "hello" |
2.5 常见启动异常与排查
异常 1:Controller 无法形成 Quorum
现象: 日志反复打印 "Failed to find leader for epoch",节点间无法建立 Raft 连接。
排查: 检查
异常 2:Broker 注册失败
现象: Broker 日志报 "Connection to node -1 (controller/ip:9093) failed"。
排查: 确认 Controller 进程已启动;检查 Broker 的
异常 3:元数据日志未格式化
现象: 启动时日志报 "Log directory /data/kraft-controller-logs is not formatted"。
排查: 执行
现象: 日志反复打印 "Failed to find leader for epoch",节点间无法建立 Raft 连接。
排查: 检查
controller.quorum.voters 配置是否在所有节点一致;检查防火墙是否开放 9093 端口;检查节点间网络连通性(telnet IP 9093)。异常 2:Broker 注册失败
现象: Broker 日志报 "Connection to node -1 (controller/ip:9093) failed"。
排查: 确认 Controller 进程已启动;检查 Broker 的
controller.quorum.voters 是否与 Controller 一致;检查 advertised.listeners 是否配置正确。异常 3:元数据日志未格式化
现象: 启动时日志报 "Log directory /data/kraft-controller-logs is not formatted"。
排查: 执行
kafka-storage.sh format 命令,注意集群 ID 必须与首次生成的一致。
2.6 生产环境部署建议
- 硬件规划: Controller 节点 CPU ≥ 4核,内存 ≥ 8GB,磁盘使用 SSD(元数据日志对 IOPS 敏感)。Broker 节点 CPU ≥ 8核,内存 ≥ 32GB,磁盘使用多块 NVMe 做 RAID0 或 JBOD。
- 网络规划: Controller 之间延迟 ≤ 1ms,Broker 到 Controller 延迟 ≤ 3ms。建议所有节点部署在同一机房或可用区。
- 监控指标: 重点监控 Controller 的 Raft 选举延迟、日志复制延迟、Broker 的 ISR 收缩次数、分区 Leader 不平衡率。
- 版本选择: 生产环境推荐 Kafka 3.5.0 及以上版本,KRaft 模式已通过大规模生产验证。