1. Kafka 单节点 KRaft 模式部署与基础验证

Kafka 单节点 KRaft 模式部署与基础验证 学习卡片

KRaft 单节点部署的核心对象与数据流

KRaft 模式把原本由 ZooKeeper 承担的元数据管理职责内化到 Kafka 自身:每个 broker 同时充当 Controller 角色,元数据以日志形式写入 __cluster_metadata 这个内部 topic。单节点部署时,一个进程既负责元数据仲裁,也负责数据读写,因此配置的关键在于让 process.roles、node.id、controller.quorum.voters 三者自洽。

单台 Linux 主机 Kafka Broker 进程(node.id=1) Controller 角色 process.roles=broker,controller controller.quorum.voters=1@host:9093 监听端口 9093(CONTROLLER) 负责元数据仲裁与选举 Broker 角色 listeners=PLAINTEXT://:9092 log.dirs=/var/kafka-logs 监听端口 9092(PLAINTEXT) 负责消息读写与副本管理 __cluster_metadata 日志 存储主题、分区、副本等元数据 路径:/var/kafka-logs/__cluster_metadata-0 由 Controller 写入,Broker 读取 替代 ZooKeeper 的元数据存储 客户端工具 kafka-topics.sh --create kafka-console-producer.sh kafka-console-consumer.sh 通过 9092 端口连接 Broker 写入 读写 元数据同步 状态上报

部署前的关键配置项

KRaft 模式不需要 ZooKeeper,但必须显式声明节点角色和仲裁者列表。以下是最小可用的 server.properties 核心片段,假设主机 IP 为 192.168.1.10,Kafka 版本为 3.7.x:

process.roles=broker,controller
node.id=1
controller.quorum.voters=1@192.168.1.10:9093
listeners=PLAINTEXT://192.168.1.10:9092,CONTROLLER://192.168.1.10:9093
advertised.listeners=PLAINTEXT://192.168.1.10:9092
controller.listener.names=CONTROLLER
listener.security.protocol.map=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
log.dirs=/var/kafka-logs
num.partitions=1
offsets.topic.replication.factor=1
transaction.state.log.replication.factor=1
transaction.state.log.min.isr=1
注意:单节点部署时,offsets.topic.replication.factor 和 transaction.state.log.replication.factor 必须设为 1,否则内部 topic 创建会因副本数不足而失败。这是单节点 KRaft 最常见的启动阻塞点。

格式化存储目录并启动

首次启动前必须用 kafka-storage.sh 生成集群 UUID 并格式化日志目录。这个 UUID 会写入 meta.properties,后续所有节点必须一致。

# 生成集群 UUID
CLUSTER_ID=$(bin/kafka-storage.sh random-uuid)
echo "Cluster ID: $CLUSTER_ID"

# 格式化存储目录
bin/kafka-storage.sh format -t $CLUSTER_ID -c config/kraft/server.properties

# 启动 broker(前台运行,便于观察日志)
bin/kafka-server-start.sh config/kraft/server.properties

启动日志中应出现以下关键行,用于确认 KRaft 仲裁已就绪:

  • [RaftManager nodeId=1] Completed transition to Leader —— 本节点成为 Controller Leader
  • [KafkaServer id=1] started —— Broker 服务启动完成
  • [SocketServer listenerName=PLAINTEXT] Awaiting socket connections on 192.168.1.10:9092 —— 客户端监听就绪

创建测试主题并完成生产消费闭环

验证分三步:创建主题、生产消息、消费消息。每一步都对应一个可观察的结果。

# 1. 创建测试主题
bin/kafka-topics.sh --create \
  --topic quickstart-events \
  --bootstrap-server 192.168.1.10:9092 \
  --partitions 1 \
  --replication-factor 1

# 2. 查看主题详情,确认分区与副本分配
bin/kafka-topics.sh --describe \
  --topic quickstart-events \
  --bootstrap-server 192.168.1.10:9092

# 3. 生产消息(输入后按 Ctrl+D 结束)
bin/kafka-console-producer.sh \
  --topic quickstart-events \
  --bootstrap-server 192.168.1.10:9092
> hello-kraft
> second-message

# 4. 消费消息(从头读取)
bin/kafka-console-consumer.sh \
  --topic quickstart-events \
  --bootstrap-server 192.168.1.10:9092 \
  --from-beginning
结果判读:消费者应输出 hello-kraft 和 second-message。如果只看到主题创建成功但消费无输出,优先检查 --from-beginning 是否遗漏,以及生产者是否真正发送了消息(控制台生产者需要回车换行后才发送)。

元数据存储验证

KRaft 模式下,主题元数据不再存于 ZooKeeper,而是写入 __cluster_metadata 内部 topic。可以通过以下命令确认元数据日志已生成:

# 查看日志目录结构
ls -la /var/kafka-logs/__cluster_metadata-0/

# 应看到 00000000000000000000.log 等分段文件
# 以及 meta.properties 中的 cluster.id 与 node.id

同时可用 kafka-metadata-quorum.sh 查看仲裁状态:

bin/kafka-metadata-quorum.sh \
  --bootstrap-server 192.168.1.10:9092 \
  describe --status

输出中 CurrentVoters 应包含 1@192.168.1.10:9093,LeaderId 为 1,CurrentObservers 为空。这表示单节点仲裁正常运行。

常见启动失败与排查

现象可能原因排查动作
启动报 InconsistentClusterIdException格式化时使用的 UUID 与 meta.properties 中不一致检查 log.dirs 下 meta.properties 的 cluster.id,重新格式化或清理目录
启动报 No readable meta.properties files未执行 kafka-storage.sh format先格式化再启动
客户端连接被拒绝advertised.listeners 配置为 localhost 或错误 IP改为客户端可访问的主机 IP,重启 broker
内部 topic 创建失败副本因子大于可用 broker 数将 offsets.topic.replication.factor 等设为 1

可复用的验证清单

  • 进程角色:process.roles=broker,controller 已设置
  • 节点 ID:node.id=1 与 controller.quorum.voters 中的 ID 一致
  • 仲裁者:controller.quorum.voters=1@主机IP:9093 可被本机解析
  • 监听器:listeners 同时包含 PLAINTEXT 和 CONTROLLER,且 advertised.listeners 使用客户端可达 IP
  • 存储:已执行 kafka-storage.sh format,meta.properties 存在
  • 启动日志:出现 Completed transition to Leader 与 KafkaServer id=1 started
  • 主题:kafka-topics.sh --describe 显示分区 1、副本 1、Leader 为 1
  • 闭环:生产者发送的消息能被消费者从 beginning 读出
  • 元数据:kafka-metadata-quorum.sh describe --status 显示 LeaderId=1、CurrentVoters 含本节点