Kafka从入门到精通

基于 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 个节点上