基于 KRaft 模式(Kafka 3.x 及以上版本,去 ZooKeeper)的集群搭建方案。
KRaft 是 Kafka 自 3.3.1 版本起生产可用的新模式,它通过内置的 Raft 共识协议替代了外部 ZooKeeper,让集群部署和运维变得更简单。
对于3节点集群,官方推荐配置是 3 个节点同时承担 Broker 和 Controller 角色(即 Combined 模式)。这个方案资源利用率高,部署也相对简单。
一、准备3节点虚拟机环境
1.1准备jdk环境
powershell
[root@localhost kafka]# java -version
openjdk version "17.0.19" 2026-04-21
OpenJDK Runtime Environment Temurin-17.0.19+10 (build 17.0.19+10)
OpenJDK 64-Bit Server VM Temurin-17.0.19+10 (build 17.0.19+10, mixed mode, sharing)
1.2主机名与解析
powershell
[root@localhost kafka]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
10.0.0.132 kafka1
10.0.0.133 kafka2
10.0.0.134 kafka3
二、部署3节点Kafka集群
2.1下载kafka安装包并解压
/opt/kafka
powershell
wget https://archive.apache.org/dist/kafka/3.9.0/kafka_2.12-3.9.0.tgz

2.2修改配置文件
node.id 和 advertised.listeners 在每台机器上必须是唯一的。对于 kafka2,node.id=2, advertised.listeners=PLAINTEXT://kafka2:9092;对于 kafka3 同理。
第一台
powershell
[root@localhost kafka]# cat config/kafka.properties
properties
# 唯一标识,每台机器不同
node.id=1
# 角色:同时作为 Broker 和 Controller
process.roles=broker,controller
# 监听器配置
# PLAINTEXT://:9092 用于客户端通信
# CONTROLLER://:9093 用于内部 Raft 共识
listeners=PLAINTEXT://:9092,CONTROLLER://:9093
# 广播地址,必须配置为客户端和集群内其他节点能访问的地址
advertised.listeners=PLAINTEXT://kafka1:9092
# 控制器监听器名称,必须与 listeners 中的对应
controller.listener.names=CONTROLLER
# 安全协议映射
listener.security.protocol.map=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
# 集群控制器列表,格式为 node.id@主机名:端口
controller.quorum.voters=1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
# 日志存储目录
log.dirs=/tmp/kafka-logs
# 为集群设置默认副本因子,非常重要!
default.replication.factor=3
min.insync.replicas=2
第二台
powershell
[root@localhost kafka]# cat config/kafka.properties
properties
# 唯一标识,每台机器不同
node.id=2
# 角色:同时作为 Broker 和 Controller
process.roles=broker,controller
# 监听器配置
# PLAINTEXT://:9092 用于客户端通信
# CONTROLLER://:9093 用于内部 Raft 共识
listeners=PLAINTEXT://:9092,CONTROLLER://:9093
# 广播地址,必须配置为客户端和集群内其他节点能访问的地址
advertised.listeners=PLAINTEXT://kafka2:9092
# 控制器监听器名称,必须与 listeners 中的对应
controller.listener.names=CONTROLLER
# 安全协议映射
listener.security.protocol.map=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
# 集群控制器列表,格式为 node.id@主机名:端口
controller.quorum.voters=1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
# 日志存储目录
log.dirs=/tmp/kafka-logs
# 为集群设置默认副本因子,非常重要!
default.replication.factor=3
min.insync.replicas=2
第三台
powershell
[root@localhost kafka]# cat config/kafka.properties
properties
# 唯一标识,每台机器不同
node.id=3
# 角色:同时作为 Broker 和 Controller
process.roles=broker,controller
# 监听器配置
# PLAINTEXT://:9092 用于客户端通信
# CONTROLLER://:9093 用于内部 Raft 共识
listeners=PLAINTEXT://:9092,CONTROLLER://:9093
# 广播地址,必须配置为客户端和集群内其他节点能访问的地址
advertised.listeners=PLAINTEXT://kafka3:9092
# 控制器监听器名称,必须与 listeners 中的对应
controller.listener.names=CONTROLLER
# 安全协议映射
listener.security.protocol.map=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
# 集群控制器列表,格式为 node.id@主机名:端口
controller.quorum.voters=1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
# 日志存储目录
log.dirs=/tmp/kafka-logs
# 为集群设置默认副本因子,非常重要!
default.replication.factor=3
min.insync.replicas=2
2.3启动集群
生成集群 ID:在任意一台机器上执行此命令,并记录输出的 UUID。
powershell
bash
bin/kafka-storage.sh random-uuid
- 示例输出: ABC123-DEF456-GHI789
格式化存储目录:在所有三台机器上分别执行以下命令,使用上一步生成的统一集群 ID。
powershell
bash
bin/kafka-storage.sh format --cluster-id <你生成的集群ID> --config config/kafka.properties
注意:此命令会清除 log.dirs 目录下的所有数据,仅在初次部署或重建集群时执行。
启动 Kafka 服务:在所有三台机器上分别执行,启动 Broker。
powershell
bash
bin/kafka-server-start.sh -daemon config/kafka.properties
2.4 验证集群
检查控制器状态:在任意节点执行以下命令,确认控制器选举正常。
powershell
bash
bin/kafka-metadata-quorum.sh --bootstrap-server kafka1:9092 describe --status
创建测试主题:创建一个副本因子为3的主题,验证集群的高可用功能。
powershell
bash
bin/kafka-topics.sh --create --topic test-ha --bootstrap-server kafka1:9092 --partitions 3 --replication-factor 3
查看主题详情:确认分区 Leader 和副本分布在不同 Broker 上。
powershell
bash
bin/kafka-topics.sh --describe --topic test-ha --bootstrap-server kafka1:9092
模拟故障测试:停止其中一个 Broker 的进程(如 kafka2),然后尝试向 test-ha 主题生产和消费消息,验证服务的连续性。
💡 关键配置与运维要点
min.insync.replicas=2:配合 replication-factor=3,这条配置保证了在至少2个副本同步成功后才算写入完成,是数据不丢失的关键。
生产者 acks=all:生产端配置 acks=all 或 acks=-1,与 Broker 端的 min.insync.replicas 配合,实现最强数据可靠性。
监控是关键:生产环境务必监控 UnderReplicatedPartitions(未充分复制的分区数)和 ISR(同步副本集)的收缩情况,这直接反映了集群的健康度。
三、集群生产和消费验证
3.1生产数据
方式一:控制台生产者(交互式)
在任意一个节点上执行:
powershell
bash
bin/kafka-console-producer.sh --bootstrap-server kafka1:9092,kafka2:9092,kafka3:9092 --topic test-topic
然后输入消息,每行一条:
text
hello kafka cluster
message 1
message 2
按 Ctrl+C 退出。
方式二:单条消息生产(脚本方式)
powershell
bash
echo "test message $(date)" | bin/kafka-console-producer.sh --bootstrap-server kafka1:9092,kafka2:9092,kafka3:9092 --topic test-topic
方式三:从文件批量生产
bash
- 准备消息文件
powershell
echo -e "line1\nline2\nline3" > messages.txt
- 批量发送
powershell
bin/kafka-console-producer.sh --bootstrap-server kafka1:9092,kafka2:9092,kafka3:9092 --topic test-topic < messages.txt
3.2 消费数据
方式一:从头消费(查看所有历史消息)
powershell
bash
bin/kafka-console-consumer.sh --bootstrap-server kafka1:9092,kafka2:9092,kafka3:9092 --topic test-topic --from-beginning
方式二:只消费最新消息(不读历史)
powershell
bash
bin/kafka-console-consumer.sh --bootstrap-server kafka1:9092,kafka2:9092,kafka3:9092 --topic test-topic
方式三:指定消费者组(便于管理偏移量)
powershell
bash
bin/kafka-console-consumer.sh --bootstrap-server kafka1:9092,kafka2:9092,kafka3:9092 --topic test-topic --group my-group --from-beginning
方式四:消费指定数量的消息后自动退出
powershell
bash
bin/kafka-console-consumer.sh --bootstrap-server kafka1:9092,kafka2:9092,kafka3:9092 --topic test-topic --from-beginning --max-messages 10
完整验证流程
终端 1:启动生产者(持续发送)
powershell
bash
bin/kafka-console-producer.sh --bootstrap-server kafka1:9092,kafka2:9092,kafka3:9092 --topic test-topic
输入几条消息后保持运行。
终端 2:启动消费者(实时查看)
powershell
bash
bin/kafka-console-consumer.sh --bootstrap-server kafka1:9092,kafka2:9092,kafka3:9092 --topic test-topic --from-beginning
应该能看到终端 1 发送的所有消息。
终端 3:验证消费者组状态
bash
- 查看消费者组列表
powershell
bin/kafka-consumer-groups.sh --bootstrap-server kafka1:9092,kafka2:9092,kafka3:9092 --list
- 查看指定组的消费进度
powershell
bin/kafka-consumer-groups.sh --bootstrap-server kafka1:9092,kafka2:9092,kafka3:9092 --describe --group my-group
高可用性测试(验证集群容错)
测试 1:停止一个 Broker,看生产和消费是否继续
bash
- 在 kafka2 上停止服务
powershell
pkill -9 -f kafka-server-start
- 在 kafka1 上继续生产消息
powershell
echo "test after broker down" | bin/kafka-console-producer.sh --bootstrap-server kafka1:9092,kafka2:9092,kafka3:9092 --topic test-topic
- 消费消息(应该还能正常消费)
powershell
bin/kafka-console-consumer.sh --bootstrap-server kafka1:9092,kafka2:9092,kafka3:9092 --topic test-topic --from-beginning --max-messages 1
测试 2:查看分区 Leader 重新分配
bash
- 查看主题详情,确认 Leader 已切换到其他节点
powershell
bin/kafka-topics.sh --bootstrap-server kafka1:9092,kafka2:9092,kafka3:9092 --describe --topic test-topic
🛠️ 常用生产和消费参数
生产者高级参数
powershell
bash
bin/kafka-console-producer.sh \
--bootstrap-server kafka1:9092,kafka2:9092,kafka3:9092 \
--topic test-topic \
--producer-property acks=all \
--producer-property compression.type=gzip \
--producer-property batch.size=16384
参数 说明 推荐值
acks=all 所有副本确认后才算成功 生产环境必配
compression.type 压缩类型 gzip 或 snappy
batch.size 批量大小 16384 (16KB)
消费者高级参数
powershell
bash
bin/kafka-console-consumer.sh \
--bootstrap-server kafka1:9092,kafka2:9092,kafka3:9092 \
--topic test-topic \
--group my-group \
--from-beginning \
--consumer-property fetch.min.bytes=1024 \
--consumer-property fetch.max.wait.ms=500
参数 说明
fetch.min.bytes 每次拉取的最小数据量
fetch.max.wait.ms 等待数据的最长时间
max.poll.records 每次拉取的最大消息数
💡 集群与单节点的关键区别
操作 单节点 集群(3节点)
Bootstrap 地址 localhost:9092 kafka1:9092,kafka2:9092,kafka3:9092
副本因子 --replication-factor 1 --replication-factor 3(推荐)
可用性 一台挂了全部不可用 一台挂了仍可继续
数据可靠性 低(无副本) 高(3副本)
✅ 验证清单
执行完所有测试后,确认以下功能正常:
生产者能成功发送消息(控制台无报错)
消费者能看到历史消息(--from-beginning)
消费者能实时看到新消息(生产者输入后立即显示)
消费者组能查询到偏移量和 Lag
停止一个 Broker 后,生产和消费仍然正常
主题副本分布在所有 3 个节点上