3. Kafka 集群环境搭建:单机与集群模式部署、ZooKeeper/KRaft 配置、常用命令行工具

Kafka 的运行模式经历了从“强依赖 ZooKeeper”到“内置 KRaft 共识”的演进。本章将覆盖两种模式下的单机与集群搭建步骤,并介绍日常运维中最常用的命令行工具。无论你选择哪种模式,理解其架构差异是第一步。

3.1 架构模式对比:ZooKeeper 模式 vs. KRaft 模式

在 Kafka 2.8 之前,元数据(Broker 注册、Topic 分区分配、Controller 选举)全部由 ZooKeeper 管理。Kafka 2.8 开始引入 KRaft(Kafka Raft),将元数据存储在 Kafka 内部 Topic __cluster_metadata 中,不再依赖外部 ZooKeeper。KRaft 模式在 Kafka 3.x 中达到生产就绪状态。

对比维度 ZooKeeper 模式 KRaft 模式
外部依赖 需要独立部署 ZooKeeper 集群(至少 3 节点) 无外部依赖,Kafka 自身管理元数据
Controller 选举 通过 ZooKeeper 临时节点 + 监听机制 基于 Raft 协议在 Controller 节点间选举
元数据存储 ZooKeeper 的 ZNode 树 内部 Topic __cluster_metadata(日志存储)
部署复杂度 高(需维护两套集群) 低(一套集群即可)
运维开销 需监控 ZK 健康、Session 超时、OOM 减少一个故障域,运维更简单
生产推荐 Kafka 2.x 及早期 3.x 的主流选择 Kafka 3.5+ 新项目推荐,社区主力演进方向
选型建议: 如果你是新建项目且 Kafka 版本 ≥ 3.5,优先选择 KRaft 模式。如果已有 ZooKeeper 基础设施或需要与旧版工具链兼容,可继续使用 ZooKeeper 模式。本课程后续章节的“因子漂移巡查”案例基于 KRaft 模式演示。

3.2 单机模式部署(KRaft 模式)

单机模式用于开发测试。以下步骤基于 Kafka 3.6+ 的 KRaft 模式,无需安装 ZooKeeper。

  1. 下载解压
    wget https://downloads.apache.org/kafka/3.6.0/kafka_2.13-3.6.0.tgz
    tar -xzf kafka_2.13-3.6.0.tgz
    cd kafka_2.13-3.6.0
  2. 生成集群 ID 并格式化存储目录
    KAFKA_CLUSTER_ID="$(bin/kafka-storage.sh random-uuid)"
    bin/kafka-storage.sh format -t $KAFKA_CLUSTER_ID -c config/kraft/server.properties
  3. 启动 Kafka 服务
    bin/kafka-server-start.sh config/kraft/server.properties
  4. 验证启动
    bin/kafka-topics.sh --bootstrap-server localhost:9092 --list

    返回空列表即表示服务正常。

注意: KRaft 模式下 server.properties 必须配置 process.roles=broker,controller(单机组合角色)或 process.roles=broker(纯 Broker)。单机测试建议使用组合角色,避免额外启动 Controller 进程。

3.3 集群模式部署(KRaft 模式,3 节点)

生产环境至少需要 3 个 Controller 节点(或组合角色节点)以保证 Raft 多数派。以下以 3 台机器(node1、node2、node3)为例。

3.3.1 配置节点属性

每个节点的 config/kraft/server.properties 核心配置如下:

配置项 node1 node2 node3
node.id 1 2 3
process.roles broker,controller broker,controller broker,controller
controller.quorum.voters 1@node1:9093,2@node2:9093,3@node3:9093 同左 同左
listeners PLAINTEXT://node1:9092,CONTROLLER://node1:9093 PLAINTEXT://node2:9092,CONTROLLER://node2:9093 PLAINTEXT://node3:9092,CONTROLLER://node3:9093
advertised.listeners PLAINTEXT://node1:9092 PLAINTEXT://node2:9092 PLAINTEXT://node3:9092
log.dirs /data/kafka/logs /data/kafka/logs /data/kafka/logs

3.3.2 格式化与启动

在所有节点上执行:

# 生成相同的集群 ID(只需在 node1 生成,复制到其他节点)
KAFKA_CLUSTER_ID="$(bin/kafka-storage.sh random-uuid)"
echo $KAFKA_CLUSTER_ID   # 记录此 ID

# 每个节点用相同 ID 格式化
bin/kafka-storage.sh format -t <相同集群ID> -c config/kraft/server.properties

# 启动服务
bin/kafka-server-start.sh config/kraft/server.properties

3.3.3 验证集群

# 在任意节点查看集群 Broker 列表
bin/kafka-broker-api-versions.sh --bootstrap-server node1:9092

# 创建测试 Topic
bin/kafka-topics.sh --bootstrap-server node1:9092 --create --topic test-cluster --partitions 3 --replication-factor 2

# 查看 Topic 详情
bin/kafka-topics.sh --bootstrap-server node1:9092 --describe --topic test-cluster
关键检查点: 输出中 Leader 和 Replicas 应分布在不同的 Broker 上,Isr 列表应与 Replicas 一致,表示副本同步正常。

3.4 集群模式部署(ZooKeeper 模式)

如果你维护的是旧版 Kafka 集群,以下为 ZooKeeper 模式的标准部署步骤。

3.4.1 部署 ZooKeeper 集群(3 节点)

# 每个 ZK 节点的 zoo.cfg 核心配置
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/zookeeper
clientPort=2181
server.1=node1:2888:3888
server.2=node2:2888:3888
server.3=node3:2888:3888

在 dataDir 下创建 myid 文件,内容分别为 1、2、3。

3.4.2 配置 Kafka Broker

每个 Broker 的 config/server.properties 核心配置:

broker.id=1   # 每个节点唯一
listeners=PLAINTEXT://node1:9092
advertised.listeners=PLAINTEXT://node1:9092
log.dirs=/data/kafka/logs
zookeeper.connect=node1:2181,node2:2181,node3:2181/kafka
offsets.topic.replication.factor=3

3.4.3 启动顺序

  1. 先启动所有 ZooKeeper 节点:bin/zkServer.sh start
  2. 再启动所有 Kafka Broker:bin/kafka-server-start.sh config/server.properties
ZooKeeper 模式避坑: ZooKeeper 集群必须过半存活(3 节点最多挂 1 台),否则 Kafka 集群无法对外服务。建议将 ZK 的 maxClientCnxns 从默认 60 调大,避免连接数不足。

3.5 常用命令行工具

以下为日常巡检和问题排查中最常用的 Kafka 命令行工具,所有命令均位于 bin/ 目录下。

工具名称 用途 常用示例
kafka-topics.sh Topic 的 CRUD 与详情查看 --list、--describe、--create、--alter、--delete
kafka-console-producer.sh 向 Topic 发送测试消息 --topic test --bootstrap-server localhost:9092
kafka-console-consumer.sh 从 Topic 消费消息(实时或从开头) --topic test --from-beginning --bootstrap-server localhost:9092
kafka-consumer-groups.sh 查看消费者组状态、偏移量、重置偏移 --list、--describe --group my-group、--reset-offsets
kafka-configs.sh 查看/修改 Broker、Topic、用户级别的配置 --describe --entity-type topics --entity-name test
kafka-broker-api-versions.sh 查看 Broker 支持的 API 版本 --bootstrap-server localhost:9092
kafka-log-dirs.sh 查看各 Broker 磁盘使用和日志分段信息 --describe --bootstrap-server localhost:9092
kafka-reassign-partitions.sh 手动迁移分区副本,均衡负载 --generate、--execute、--verify

3.5.1 快速验证集群健康

# 1. 查看所有 Topic
bin/kafka-topics.sh --bootstrap-server node1:9092 --list

# 2. 查看特定 Topic 的分区分布
bin/kafka-topics.sh --bootstrap-server node1:9092 --describe --topic factor-alert

# 3. 发送一条测试消息
echo '{"factor":"volatility","value":0.85,"drift":true}' | bin/kafka-console-producer.sh --topic factor-alert --bootstrap-server node1:9092

# 4. 消费测试消息(从最新开始)
bin/kafka-console-consumer.sh --topic factor-alert --bootstrap-server node1:9092

# 5. 查看消费者组偏移
bin/kafka-consumer-groups.sh --bootstrap-server node1:9092 --describe --group factor-drift-group

3.6 部署架构总览

下图展示了 KRaft 模式下 3 节点集群的组件关系与内部通信路径。每个节点同时承担 Broker 和 Controller 角色,通过 Raft 协议在 Controller 层达成共识,Broker 层负责处理客户端请求。

KRaft 模式 3 节点集群架构 KRaft 模式 3 节点集群架构 节点 1 (node1) Broker ID: 1 Controller: 是 端口 9092 (数据) 端口 9093 (Raft) 节点 2 (node2) Broker ID: 2 Controller: 是 端口 9092 (数据) 端口 9093 (Raft) 节点 3 (node3) Broker ID: 3 Controller: 是 端口 9092 (数据) 端口 9093 (Raft) 数据复制层(Broker 间) 分区 Leader/Follower 副本通过 Kafka 内部协议同步数据 客户端(Producer / Consumer) 实线:Raft 共识(Controller 间) 虚线:数据复制(Broker 间) 箭头:客户端请求

3.7 部署检查清单

无论选择哪种模式,部署完成后建议逐项核对以下清单:

  • 网络连通性: 各节点间 9092(数据)、9093(Raft/Controller)、2181(ZooKeeper)端口互通。
  • 磁盘容量: log.dirs 所在分区至少预留 20% 空闲空间,建议使用独立数据盘。
  • JVM 堆内存: 生产环境 Broker 堆内存建议 4G~8G,Controller 节点可适当降低。
  • Topic 副本因子: 至少设置为 2,关键 Topic 设置为 3。
  • 最小 ISR: min.insync.replicas 建议设置为副本因子减 1,保证写入一致性。
  • 日志保留策略: 根据数据量设置 log.retention.hours 或 log.retention.bytes,避免磁盘写满。
快速验证命令: 使用 kafka-broker-api-versions.sh --bootstrap-server node1:9092 可以快速确认所有 Broker 是否在线且版本一致。如果输出中缺少某个 Broker 的版本信息,说明该节点未成功加入集群。