Kafka 4.0 KRaft模式完全指南_kafka kraft
在 Kafka 使用 Zookeeper 的架构下,Broker 启动后会通过 Zookeeper 选举一个 broker 会成为 controller,用于管理集群元数据。
在使用KRaft的架构中,支持 Controller 独立于 Broker 运行,每个 controller 可以是活跃节点或热备节点。kraft可以理解成是 Kafka 的 controller 集群,内部使用了 raft 一致性协议,管理集群元数据。
配置
process.roles
在 KRaft 模式下,每个 Kafka 服务器可以通过 process.roles
属性配置为 controller、broker 或两者兼有。该属性支持以下值:
- 若
process.roles
设为broker
,则服务器作为 broker 运行。 - 若
process.roles
设为controller
,则服务器作为 controller 运行。 - 若
process.roles
设为broker,controller
,则服务器同时作为 broker 和 controller 运行(称为 combined 模式)。
Combined 模式(同时运行 broker 和 controller)适用于小型场景(如开发环境),但缺点是 controller 的隔离性较差。例如,在此模式下无法独立滚动升级或扩缩容 controller。生产环境不推荐使用 combined 模式。
Controllers
在 KRaft 模式下,需指定部分 Kafka 服务器作为 controller。这些 controller 参与元数据仲裁(metadata quorum),每个 controller 可以是活跃节点或热备节点。
通常建议选择 3 或 5 台服务器作为 controller,具体取决于成本及集群需容忍的并发故障数:
- 3 controllers:可容忍 1 台故障。
- 5 controllers:可容忍 2 台故障。
所有 Kafka 服务器需通过 controller.quorum.bootstrap.servers
属性发现活跃 controller。该属性需列出 controller 的主机与端口信息,例如:
controller.quorum.bootstrap.servers=host1:port1,host2:port2,host3:port3
示例配置(假设集群有 3 台 controller):
process.roles=controller node.id=1 listeners=CONTROLLER://controller1.example.com:9093 controller.quorum.bootstrap.servers=controller1.example.com:9093,controller2.example.com:9093,controller3.example.com:9093 controller.listener.names=CONTROLLER
注意:所有 broker 和 controller 必须设置 controller.quorum.bootstrap.servers
。
静态仲裁 vs 动态仲裁
运行 KRaft 有两种方法:使用静态控制器仲裁的旧方法,以及使用 KIP-853 动态控制器仲裁的新方法。
- 静态仲裁:需在
controller.quorum.voters
中列出所有 controller 的 ID、主机名和端口。 - 动态仲裁:通过
controller.quorum.bootstrap.servers
发现仲裁(类似客户端的bootstrap.servers
)。
判断仲裁类型:
bin/kafka-features.sh --bootstrap-controller localhost:9093 describe
- 若
kraft.version
为0
或未显示,则为静态仲裁。 - 若
kraft.version
为1+
,则为动态仲裁。
动态仲裁格式化:
bin/kafka-storage.sh format -t KAFKA_CLUSTER_ID --feature kraft.version=1 -c controller_static.properties
注意:4.0当前不支持将静态仲裁转为动态仲裁,未来版本将支持。
生成集群 ID
使用 bin/kafka-storage.sh random-uuid
生成集群 ID,并在格式化集群服务器时通过 bin/kafka-storage.sh format
指定此 ID。
与旧版区别:旧版 Kafka 会自动格式化空存储目录并生成集群 ID,但新版要求显式操作以避免因自动格式化掩盖错误(尤其是 controller 和 broker 的元数据日志目录)。
启动 Controller
以下是动态仲裁 Controller 集群的初始化启动过程。
独立 Controller 启动
推荐先启动单节点 controller,再动态添加其他 controller。启动命令:
bin/kafka-storage.sh format --cluster-id <CLUSTER_ID> --standalone --config config/controller.properties
此命令会:
- 在元数据目录生成
meta.properties
(包含随机directory.id
)。 - 创建初始快照
00000000000000000000-0000000000.checkpoint
,使当前节点成为仲裁的唯一投票者。
多 Controller 启动
使用 --initial-controllers
标志同时启动多个 controller:
CLUSTER_ID=\"$(bin/kafka-storage.sh random-uuid)\" CONTROLLER_0_UUID=\"$(bin/kafka-storage.sh random-uuid)\" CONTROLLER_1_UUID=\"$(bin/kafka-storage.sh random-uuid)\" CONTROLLER_2_UUID=\"$(bin/kafka-storage.sh random-uuid)\" # 每个 controller 执行 bin/kafka-storage.sh format --cluster-id ${CLUSTER_ID} \\ --initial-controllers \"0@controller-0:1234:${CONTROLLER_0_UUID},1@controller-1:1234:${CONTROLLER_1_UUID},2@controller-2:1234:${CONTROLLER_2_UUID}\" \\ --config config/controller.properties
快照中将包含所有 controller 的 VotersRecord
。需确保所有 controller 的 --initial-controllers
值一致。
添加 Controller
- 格式化并启动新 controller。向现有集群添加 broker 或 controller 时,使用
--no-initial-controllers
标志:
bin/kafka-storage.sh format --cluster-id --config config/server.properties --no-initial-controllers
- 监控同步状态:
bin/kafka-metadata-quorum.sh describe --replication
- 同步完成后添加:
# 使用 broker 端点 bin/kafka-metadata-quorum.sh --bootstrap-server localhost:9092 add-controller # 使用 controller 端点 bin/kafka-metadata-quorum.sh --bootstrap-controller localhost:9093 add-controller
移除 Controller
推荐先关闭待移除的 controller,再执行:
# 使用 broker 端点 bin/kafka-metadata-quorum.sh --bootstrap-server localhost:9092 remove-controller --controller-id <id> --controller-directory-id <directory-id> # 使用 controller 端点 bin/kafka-metadata-quorum.sh --bootstrap-controller localhost:9093 remove-controller --controller-id <id> --controller-directory-id <directory-id>
静态 Controller 启动过程
controller.properties
controller.quorum.voters=0@controller-0:1234,1@controller-1:1234,2@controller-2:1234
格式化并启动
bin/kafka-storage.sh format --cluster-id $KAFKA_CLUSTER_ID --config config/controller.properties --no-initial-controllersbin/kafka-server-start.sh config/controller.properties
KRaft 调试工具
Metadata Quorum Tool
kafka-metadata-quorum.sh 工具可用于描述集群元数据分区的运行时状态。例如,以下命令显示元数据仲裁的摘要:
bin/kafka-metadata-quorum.sh --bootstrap-server localhost:9092 describe --status
输出示例:
ClusterId: fMCL8kv1SWm87L_Md-I2hg LeaderId: 3002 LeaderEpoch: 2 HighWatermark: 10 MaxFollowerLag: 0 CurrentVoters: [{\"id\": 3000, \"directoryId\": \"ILZ5MPTeRWakmJu99uBJCA\"}, ...]
Dump Log Tool
解析元数据日志和快照:
bin/kafka-dump-log.sh --cluster-metadata-decoder --files metadata_log_dir/__cluster_metadata-0/00000000000000000000.log bin/kafka-dump-log.sh --cluster-metadata-decoder --files metadata_log_dir/__cluster_metadata-0/00000000000000000100-0000000001.checkpoint
Metadata Shell
kafka-metadata-shell.sh 工具可用于以交互方式检查集群元数据分区的状态:
bin/kafka-metadata-shell.sh --snapshot metadata_log_dir/__cluster_metadata-0/00000000000000000000.checkpoint >> ls / >> cat /topics/foo/0/data
部署建议
- 生产环境避免 combined 模式(
process.roles=broker,controller
)。 - 至少部署 3 台 controller(容忍 1 故障)或 5 台(容忍 2 故障)。
- 建议为 controller 分配 5GB 内存和 5GB 元数据日志目录空间。
ZooKeeper 迁移至 KRaft
需使用 Kafka 3.9 作为桥接版本,具体步骤参考 3.9 文档中的迁移指南。
🌟 消息队列专家服务
提供 Kafka/Pulsar 全栈解决方案
▌ 生产环境架构设计 ▌ 集群雪崩故障根治 ▌ 性能调优实战