Kafka 2.8 发布至今仍被不少人提起,不是因为新增了多少业务功能,而是它第一次正式提供了去除 Zookeeper 的部署模式——KRaft。很多团队因为这个特性开始折腾无 ZK 集群,但实际落地时发现,配置文件变了、启动流程变了、连元数据管理逻辑都得重新理解,照着老教程写必然踩坑。这篇内容就是我基于真实环境反复试错后的完整记录,从架构原理讲到三节点集群的配置细节,再到常见故障的排查思路,争取让你照着走一遍就能跑起来,省掉自己趟雷的时间。
1. 无 Zookeeper 模式到底改了什么
1.1 为什么一定要甩掉 Zookeeper
先聊一个很现实的问题:Zookeeper 在 Kafka 里到底干什么活,为什么这么多人想把它换掉。
Kafka 的元数据——包括主题列表、分区分配关系、副本状态、配置信息、消费组进度——长期以来都存放在 Zookeeper 中。Broker 启动时要向 ZK 注册自己,控制器(Controller)的选举也依赖 ZK 的临时节点和 Watch 机制,消费者组协调器同样需要 ZK 来维护成员状态。可以说 ZK 是 Kafka 的大脑和神经中枢,但它和 Kafka 是两套独立的系统,部署时要单独维护一套集群,版本兼容性要小心对齐,ZK 本身又有一套选举机制和会话超时逻辑,一旦出现网络抖动或 GC 停顿,就容易引发脑裂或者元数据不一致的问题。
大概在 2020 年前后,Kafka 社区启动了 KIP-500 项目,目标就是把 Zookeeper 从 Kafka 的架构中彻底移除,改用 Kafka 内置的 Raft 协议来管理元数据。Kafka 2.8 是第一个把 KRaft 模式作为早期预览版放出来的版本,虽然当时官方明确标注了是 early access,但已经是里程碑式的变化——毕竟这意味着你可以在完全无 ZK 的情况下跑起一套 Kafka 集群。
1.2 KRaft 模式下的角色划分
KRaft 模式下,Kafka 自己承担了元数据存储和一致性保证的工作。节点角色被重新划分为两类:
- Controller(控制器):负责管理元数据,维护主题、分区、配置、ISR 等信息,并通过 Raft 协议在多个 Controller 节点之间达成共识。Controller 有三节点或五节点的高可用部署方式,担任 Leader 的节点响应外部请求。
- Broker(代理):负责处理生产消费请求,存储消息数据,和之前版本里的 Broker 职责基本一致。Broker 节点会从 Controller 那边拉取元数据更新,本地缓存一份元数据信息。
比较关键的一点是:一个进程可以同时承担 Broker 和 Controller 两种角色,这种模式叫 combined 模式,适合节点数量有限的测试环境。生产环境更推荐把 Controller 和 Broker 分开部署,也就是 dedicated 模式,这样 Controller 的性能不会被数据读写路径干扰,故障域也更清晰。
1.3 版本选择的现实考量
项目标题写的是 Kafka 2.8,这里必须提醒一句:2.8 的 KRaft 只是 Preview 级别,功能不太完整,官方文档里也明确说了“not recommended for production”。比如在 2.8 早期版本,变更分区副本、调整 ISR 之类的管理员操作还有不少限制,Controller 和 Broker 之间的协议也在快速迭代。
如果你是自己在测试环境折腾,想体验无 ZK 模式,Kafka 2.8 完全够用了,而且很多经典配置参数从 2.8 开始才稳定成型。如果是要评估生产落地,建议直接上 3.5 以上的版本,KRaft 在 3.3 之后已经能够用于生产,3.5 开始对 Controller 迁移、动态重新配置这些功能支持得比较完善。这篇博文的配置方法在 2.8~3.x 之间基本通用,差异我会在相关章节说明。
2. 集群规划与前置环境准备
2.1 节点规划与角色分配
我这次搭建的是一个三节点集群,考虑到测试目的,采用 combined 模式,三个节点同时承担 Controller 和 Broker 角色。对于 KRaft 模式,Controller 节点数必须是奇数个,三节点可以容忍一个节点故障,生产环境如果条件允许建议用五个 Controller 节点。
假设计划使用三台服务器,内网 IP 分别是 10.0.0.11、10.0.0.12、10.0.0.13,这里用 A、B、C 作为虚拟节点名替代真实主机名。每个节点的处理角色都是 broker+controller,node.id 分别设置为 1、2、3。
端口规划方面,Broker 对外服务端口用 9092(PLAINTEXT),Controller 内部通信端口用 9093(CONTROLLER)。9093 这个端口不需要暴露给客户端,它是 Controller 之间通过 Raft 协议同步元数据的通道,也是 Broker 节点向 Controller 拉取元数据的通道,所以建议走内网,不要暴露公网。
2.2 JDK 与 Kafka 安装
Kafka 2.8 要求 JDK 8 以上,我实测在 JDK 8 和 JDK 11 下跑 KRaft 模式都没有问题,推荐用 JDK 11,长期支持且 GC 表现更稳定。安装步骤不复杂,但有一些细节要提醒。
# 以 root 用户或具有 sudo 权限的用户执行 mkdir -p /opt/kafka tar -zxvf kafka_2.13-2.8.1.tgz -C /opt/kafka # 创建软链接,方便版本切换 ln -s /opt/kafka/kafka_2.13-2.8.1 /opt/kafka/current # 配置环境变量 cat >> /etc/profile << 'EOF' export KAFKA_HOME=/opt/kafka/current export PATH=$PATH:$KAFKA_HOME/bin EOF source /etc/profile注意选择以2.13开头的发行包,这是 Scala 编译版本,2.13 对于 Kafka 2.8 来说是官方推荐的编译版本,功能和兼容性有保障。安装完成后运行kafka-topics.sh --version确认版本号正常显示为 2.8.1。
2.3 目录规划与系统参数调优
数据目录建议单独挂载一块数据盘,不要放在系统盘上,避免系统日志和消息数据争抢磁盘 IO。规划目录如下:
# 数据目录 mkdir -p /data/kafka/data mkdir -p /data/kafka/meta # 日志目录(运行日志,非数据日志) mkdir -p /var/log/kafka其中/data/kafka/data是消息数据目录,对应配置文件的log.dirs;/data/kafka/meta是 KRaft 元数据目录,对应metadata.log.dir。在 KRaft 模式推出以前只有一个数据目录,现在多了metadata.log.dir,这个目录存放的是 Raft 日志和快照数据,是整个集群一致性的基石,重要性不比消息数据低,必须放在可靠的磁盘上。
系统参数上有几个值得提前检查的配置项:
# 检查文件句柄限制 ulimit -n # 建议设置 cat >> /etc/security/limits.conf << 'EOF' * soft nofile 1000000 * hard nofile 1000000 * soft nproc 65535 * hard nproc 65535 EOF # 关闭交换分区影响(视情况设置) sysctl -w vm.swappiness=10文件句柄调大是因为 Kafka 每个分区会打开大量文件句柄,分区数量多的时候很容易撞到默认的 1024 限制。vm.swappiness调到 10 左右是为了避免 CTL 触发高 GC 导致 Controller 节点短暂失联。这些都不是 KRaft 特有的要求,但既然搭新集群,一次性配置到位总归省事。
3. 核心配置文件逐项解析
3.1 server.properties 总览
KRaft 模式下的config/server.properties和旧版有很大不同,最大的变化就是新增了process.roles、node.id、controller.quorum.voters这几个核心参数,同时删掉了zookeeper.connect。我先把三个节点共用的配置骨架列出来,然后再逐个解释关键项。
# 节点角色 process.roles=broker,controller node.id=1 controller.quorum.voters=1@10.0.0.11:9093,2@10.0.0.12:9093,3@10.0.0.13:9093 # 监听器 listeners=PLAINTEXT://10.0.0.11:9092,CONTROLLER://10.0.0.11:9093 advertised.listeners=PLAINTEXT://10.0.0.11:9092 controller.listener.names=CONTROLLER inter.broker.listener.name=PLAINTEXT # 数据目录 log.dirs=/data/kafka/data metadata.log.dir=/data/kafka/meta # 其他常规配置 num.partitions=3 default.replication.factor=2 offsets.topic.replication.factor=2 transaction.state.log.replication.factor=2 transaction.state.log.min.isr=1 log.retention.hours=168 log.segment.bytes=1073741824 log.retention.check.interval.ms=300000 auto.create.topics.enable=false有三个节点需要改的只有node.id、listeners、advertised.listeners和controller.quorum.voters里对应的 IP 地址,其余保持一致就好。我强烈建议把这一份配置保存成模板,逐个节点改差异项,避免漏改或写错。
3.2 关键参数的作用与选值逻辑
逐个说说这些参数背后的逻辑,你理解了之后就不会瞎填。
process.roles取值有三种:broker、controller、broker,controller。因为我们用的是 combined 模式,所以写broker,controller。如果将来扩容专门加一台 Controller 节点,那台机器就只写controller。
node.id是每个节点的唯一标识,注意它替代了旧版的broker.id,在 KRaft 模式下所有节点——包括专属 Controller——都需要有唯一的node.id,范围从 1 开始递增就行。
controller.quorum.voters是 KRaft 最核心的一个参数,格式是id@host:port用逗号分隔,罗列所有 Controller 节点。每个节点启动时会把自己配置的 voters 列表和集群实际状态做对比,如果发现自己不在这个列表里,会被拒绝加入。这个参数在三台机器上必须完全一致,尤其不能漏节点或写错端口。
listeners和controller.listener.names要配套理解。listeners里定义了多个协议的监听地址,其中PLAINTEXT用于客户端和 Broker 间数据通信,CONTROLLER用于 Controller 间 Raft 通信。controller.listener.names指定哪些 listener 是 Controller 通信使用的,必须对应listeners里定义的协议名。在你的场景中,就是CONTROLLER。
advertised.listeners是给客户端用的连接信息。如果你用localhost测试单机,可以直接写成PLAINTEXT://localhost:9092;如果是多节点集群,必须填对客户端能访问的 IP 或域名,比如PLAINTEXT://10.0.0.11:9092。这个配置错了会出现“客户端连接成功但消息一直发不出去”的诡异现象。
metadata.log.dir是 KRaft 专用的元数据目录,这点容易忽略。旧版 Kafka 没有这个参数,早期 KRaft 版本叫meta.properties所在的目录,后来明确为metadata.log.dir。如果你的 Kafka 2.8.1 报错说找不到该参数,可以先检查是不是版本太老,2.8.0 早期版本对这个参数的支持还不够完整。
3.3 安全与认证的占位说明
上面配置里用的都是PLAINTEXT,也就是无加密、无认证的明文通信。生产环境绝不能这么干,至少要启用 SASL_SSL 或者 SSL,这一点无论是 ZK 模式还是 KRaft 模式都一样。
KRaft 模式下认证配置的位置发生了迁移,旧版在zookeeper.set.acl那套体系里配置,新版本变成了controller.quorum.*相关配置,例如controller.quorum.ssl.*或controller.quorum.sasl.*这些前缀。如果将来要加认证,配置逻辑是:Broker 之间走listener.name.sasl_ssl.*,Controller 之间走controller.quorum.sasl.*,两套机制独立配置、互不干扰。
4. 集群初始化与启动全过程
4.1 生成集群 ID 与格式化存储目录
KRaft 模式和 ZK 模式最大的操作差异就在这里:启动之前必须先执行一次格式化,生成集群元数据。格式化会写入一个唯一的集群 ID 到元数据目录中,所有节点必须使用同一个集群 ID,否则节点之间无法组成集群。
# 在一台节点上生成 UUID KAFKA_CLUSTER_ID=$(bin/kafka-storage.sh random-uuid) echo $KAFKA_CLUSTER_ID执行后得到的是一串形如e6XzZFqPRNCF6XsmU5_NKA的随机 ID。拿到这个 ID 之后,在每个节点上执行格式化。
# 在 A、B、C 三台节点上依次执行 bin/kafka-storage.sh format -t e6XzZFqPRNCF6XsmU5_NKA -c config/server.properties格式化成功后,/data/kafka/meta目录下会生成meta.properties文件,里面记录了cluster.id和node.id,可以通过cat检查确认。
这里有一个必须注意的坑:如果某个节点没有加入controller.quorum.voters列表,格式化时该节点会因为校验不过而报错。我碰到过一次把voters里的 IP 写错导致格式化失败的情况,报错信息还比较隐晦,只有自己仔细核对配置才能发现。另外,format命令会清空元数据目录,执行前要确认不会误删已有数据。当然,对全新集群来说一般不存在这个问题。
4.2 启动 Controller 与 Broker
格式化完成后就可以启动服务了。如果按照旧习惯直接用kafka-server-start.sh启动也行,现在它仍然是最常用方式,但新版也提供了职责明确的第一代工具命令。
# 在 A、B、C 三个节点上依次启动 bin/kafka-server-start.sh -daemon config/server.properties进程是否起来,可以从日志确认:
tail -f logs/server.log启动日志里重点关注两个输出:Kafka Server started表示 Broker 启动完成;Controller server started则表示当前节点成功参与了 Controller 角色。考虑到我们使用的是 combined 模式,同一进程会异步启动两部分功能,所以两个日志都会出现。
注意如果启动顺序不对,比如刚开始只有 A 节点启动,它会在日志里反复打印类似Failed to connect to controller或者Cannot connect的提示,这个不用担心,等 B、C 节点启动到位后会自动恢复正常。Raft 协议本身就能容忍这种启动顺序问题,无需手动干预。
4.3 创建主题与基本验证
集群启动后,先创建一个测试主题验证整体链路。
bin/kafka-topics.sh --bootstrap-server 10.0.0.11:9092 --create \ --topic krft-test \ --partitions 3 --replication-factor 2创建成功后,可以通过describe命令确认分区的副本分配情况:
bin/kafka-topics.sh --bootstrap-server 10.0.0.11:9092 --describe --topic krft-test输出会类似:
Topic: krft-test PartitionCount: 3 ReplicationFactor: 2 Topic: krft-test Partition: 0 Leader: 1 Replicas: 1,2 Isr: 1,2 Topic: krft-test Partition: 1 Leader: 2 Replicas: 2,3 Isr: 2,3 Topic: krft-test Partition: 2 Leader: 3 Replicas: 3,1 Isr: 3,1Leader 和 Isr 都正常列出,说明节点间通信没问题。如果这里出现Leader: -1或者 ISR 列表为空,大概率是 Controller 选举出了问题,这个我在后面的排查章节详细展开。
最后用生产消费测试确认端到端可用:
# 终端1:消费 bin/kafka-console-consumer.sh --bootstrap-server 10.0.0.11:9092 \ --topic krft-test --from-beginning # 终端2:生产 bin/kafka-console-producer.sh --bootstrap-server 10.0.0.11:9092 \ --topic krft-test5. 故障转移与高可用实测
5.1 停掉一台节点验证自动恢复
集群搭好了,最关心的事情就是:某台节点挂了之后,集群还能不能正常工作。
先看一下当前 Controller 是哪个节点。在任意 Broker 上执行:
bin/kafka-metadata-quorum.sh --bootstrap-server 10.0.0.11:9092 describe --status输出里会显示当前 Leader 是哪个 node.id。因为这个集群用的是 combined 模式,每个节点都可能成为 Controller Leader。
假设当前 Controller Leader 是节点 A,接下来我停掉节点 B 来验证故障转移。注意停掉非当前 Leader 的节点,是为了验证在正常集群压下负载时,副本重新分配和消息生产消费是否能正常存活。
# 在节点B上 bin/kafka-server-stop.sh等待几秒后,再次查看描述:
bin/kafka-topics.sh --bootstrap-server 10.0.0.11:9092 --describe --topic krft-test你会发现 B 节点原本作为 Leader 的分区(比如 partition 1)自动切换到其他节点的副本,Isr 列表里也移除了 B 节点。同时再执行一次kafka-metadata-quorum.sh describe --status,Controller Leader 应该转移到了 A 或 C。整个过程无需人工干预,Raft 协议会自行完成 Leader 再选举。如果你在生产消费测试中发现消息仍然正常收发,说明故障转移已经生效。
5.2 重启节点与数据同步验证
把 B 节点重新启动后,它会重新加入集群。观察日志会看到它正在从其他节点拷贝缺失的数据副本,一段时间后describe输出中 B 节点又回到 ISR 列表。这个“追赶”过程不需要手动触发,Controller 会自动将 B 标记为Online并同步增量数据。
一个需要留意的细节是:KRaft 模式下的元数据同步和旧版不同,它不走 ZK Watch,而是基于 Raft 日志的快照和增量推送。这意味着 Controller 和 Broker 之间会保持一条长连接,Broker 定期向 Controller 发送 FollowerFetchRequest 来拉取元数据变更。如果节点之间的网络非常不稳定,可能导致元数据长期不同步,表现就是主题创建了但某些节点看不到。
5.3 保留测试结论后的思考
实测下来,KRaft 模式在三节点 combined 部署下,稳态表现和故障转移能力是及格的。只要 Controller 节点保持多数在线(三节点中至少两个),就能持续对外提供元数据服务。
不过必须提醒的是,如果 Controller 三个节点挂了两个,整个集群会进入只读或拒绝服务状态——因为元数据无法更新,任何创建主题、修改分区、消费组协调等操作都会失败,已存在于各 Broker 上的老分区数据还可以被读取,但新写入也会因为协调器不可用而受影响。旧版 ZK 模式里,ZK 集群挂了同样会导致集群不可用。这个风险点没有本质变化,所以架构设计时还是要把 Controller 节点故障域尽量拉开。
6. 从 Zookeeper 模式迁移到 KRaft 的路径
6.1 迁移工具与限制
如果你已经有一套跑在 ZK 模式下的 Kafka 集群,想迁到 KRaft 模式,Kafka 提供了一条官方支持的工具路径,从某个版本开始可以用kafka-storage.sh附带的方式做集群级元数据迁移。不过在 2.8 这个早期版本里,迁移工具还不成熟,官方一度建议直接“新集群 + 数据重放”,这也可能是很多人选择直接用最新稳定版的理由。
突出一点:不管工具成熟度如何,线上直接原地切换是不推荐的。KRaft 和 ZK 模式的元数据模型、Broker ID 管理、日志存储格式都不完全一致,原地迁移的风险远高于新老集群并行切换。
如果你只是学习体验,我的建议是直接起一套全新的 KRaft 集群,不折腾迁移。迁移问题等升级到 3.5+ 版本再规划会更轻松,那时候的迁移工具已经能够处理不少边界情况。
6.2 多环境并行与流量切换
比较稳妥的做法是搭建一套独立的 KRaft 环境,把生产环境的流量通过双写或复制工具同步过去,观察稳定后再逐步切读。这个思路在 Kafka 社区不算新鲜,只是执行时要特别注意消费组位点的迁移,必须在切换前尽量拉平新旧集群的位点差,否则会出现消费者从头消费大量积压数据的情况。
对于个人实验来说,没必要搞这么复杂。用新环境跑跑生产消费、测测节点故障转移、验证一下控制台工具的兼容性,这些已经足够帮你建立对 KRaft 的直观认知了。
7. 常见问题与排查技巧实录
7.1 节点无法加入集群
症状:新节点启动后,日志中反复提示Failed to find current epoch或Connection to node X failed,集群元数据在这个节点上始终无法同步。
排查思路按顺序来:
- 先确认三个节点的
controller.quorum.voters是否完全一致,尤其是 IP 和端口。 - 再确认
node.id与其他节点是否冲突,每个节点必须唯一。 - 然后确认
metadata.log.dir下的meta.properties里的cluster.id是否一致,不一致说明格式化时用的 UUID 不一样,必须重新格式化。
这里最容易踩的坑就是格式化时忘了把KAFKA_CLUSTER_ID写成同一个值,三个节点各生成各的,结果永远组不成集群。格式化命令建议只在一台节点上生成 UUID,其他节点直接沿用。
7.2 Controller 无法选举 Leader
症状:kafka-metadata-quorum.sh describe --status输出的 Leader 一直是空,或者状态一直停留在Transitioning。
可能原因有这么几类:
- Controller 之间的端口不通。检查 9093 端口是否被防火墙拦截,或者监听地址是否设置了
localhost。 - 节点时钟不同步。Raft 协议依赖时间比较 LogIndex 和 Term,如果三台节点时钟差太多,选举会处于混乱状态。建议所有节点配置 NTP 时间同步。
- Voters 列表缺失节点。比如只写了两个节点,第三台虽然启动了但不在仲裁集里,永远无法参与选举。
时间同步这一点以前 ZK 模式也有要求,但在 KRaft 下更为敏感,因为所有元数据写入都要通过 Raft 达成多数一致,而 Term 和 LogIndex 的推进依赖于单调递增的时钟逻辑。
7.3 客户端连接正常但无法收发消息
症状:客户端能用--bootstrap-server连上集群,创建主题列表也能看到,但生产和消费时经常超时或报Leader not available。
这个大概率与advertised.listeners配置有关。客户端先从 Broker 获取元数据,拿到的是每个分区的 Leader 节点地址,这些地址来自advertised.listeners。如果你填的是localhost:9092,客户端从别的机器访问时就会尝试连localhost,自然连不通。
解决方案很简单:advertised.listeners必须填客户端真正能访问到的 IP 或域名,不要偷懒。
7.4 元数据目录损坏怎么办
如果/data/kafka/meta目录损坏或节点意外断电导致元数据目录状态异常,节点启动时会拒绝继续服务,日志提示类似Recovery failed的信息。
首先要判断这个节点在集群中的角色。如果只是普通 Broker(combined 模式下所有节点都参与元数据,所以更麻烦),最简方案是把该节点的元数据目录清掉,重新格式化,然后让它重新加入集群。因为消息数据目录(/data/kafka/data)里保存的分区数据还在,启动后该节点会以“跟进者”身份重新从现有集群同步元数据,分区数据会做增量追赶,不需要全量重放。当然,前提是消息数据目录没有损坏,否则只能在该主题副本允许的情况下把它从集群中移除再重新加回来。
这个技巧对 ZK 模式完全无效,因为 ZK 模式下元数据在 ZK 集群里,Broker 只是数据节点。KRaft 模式下元数据在每个 Controller 节点本地都有一份,所以单个节点的元数据损坏是可以自愈的,这也算是它架构上的一个优势。
7.5 日志中的常见关键信息
排查问题时看一眼日志里的这几行会有很大帮助:
| 日志关键词 | 含义 |
|---|---|
Registered broker | Broker 成功注册到元数据层 |
Controller server started | 当前进程已完成 Controller 角色初始化 |
Kafka Server started | Broker 服务完全启动 |
Failed to connect to controller | 启动初期正常的重连提示,持续出现则异常 |
Unable to connect to metadata | 元数据通信异常,检查网络和 listener 配置 |
8. 部署过程中值得留意的几个细节
8.1 日志目录别和数据目录混用
有人图省事把logs运行日志和消息数据放到同一个目录,短期看着没事,一旦分区数量上去了,日志文件疯狂增长会挤占磁盘空间,导致消息写入失败。建议独立目录存放运行日志,并配置日志轮转。Kafka 自带的log4j.properties默认有按大小滚动策略,但保留份数建议确认一下,避免日志无限积累。
8.2 监控 Controller 节点的 Raft 指标
KRaft 模式下,Controller 节点的 Raft 状态是集群健康的核心指标。Kafka 暴露了若干 JMX 指标,例如kafka.controller:type=KafkaController,name=ActiveControllerCount、kafka.server:type=raft-metrics之类的指标。如果你搭过 Prometheus 监控,建议重点盯这几个:
- ActiveControllerCount:正常值为 1,大于 1 说明脑裂,小于 1 说明没有 Controller 可用。
- 元数据日志同步延迟:单位通常是毫秒,持续增长说明网络或磁盘有问题。
- 未同步副本数量:在 KRaft 模式下对应的是元数据分区 ISR 收缩情况。
其实哪怕没有监控系统,只要定期手动跑一次kafka-metadata-quorum.sh describe --status确认 Controller 正常、ISR 完整,就已经能防住大部分风险了。
8.3 节点扩容时怎么操作
KRaft 模式下扩容比 ZK 模式简单,因为不需要额外搭 ZK 节点。假设当前三节点集群要扩成五节点:
- 新节点按照相同配置修改
node.id,加入listeners。 - 在所有现有节点和新节点的
controller.quorum.voters中加入新节点信息。 - 依次重启现有节点使配置生效,然后启动新节点。
- 新节点会开始同步元数据日志。
注意:因为要改controller.quorum.voters,所以现有节点需要滚动重启,顺序上建议从非当前 Controller Leader 的节点开始,最后再动 Leader,把对读写服务的影响降到最低。
8.4 删数据千万别删错目录
由于 KRaft 模式多了一个metadata.log.dir,一些小伙伴在清理磁盘时容易误把元数据目录当成普通日志清掉,结果节点启动直接崩溃。牢记:/data/kafka/meta和/data/kafka/data都属于 Kafka 的核心数据,删除任何一个都会导致节点状态异常。运行日志放/var/log/kafka,那是唯一可以放心清理的目录。
9. 我的最终体验总结
Kafka 2.8 的 KRaft 模式虽然只是个 preview,但它验证了一条可行的路径:没有 Zookeeper,Kafka 依然能跑得很稳,甚至元数据管理更直接、组件更少。如果你时间有限,建议先在单机或三节点测试环境里把这个模式摸熟,等你要面对生产集群时,会发现那些踩坑经验全部能复用。
从实际体验来说,KRaft 模式最让我惊喜的不是性能提升(说实话单论吞吐和老版本差别不大),而是运维心智负担的下降——不用再维护一套 ZK 集群,不用再担心 ZK 和 Kafka 版本兼容问题,故障排查链路直接从两套系统简化成一套。光这一点,就足够让这个模式成为 Kafka 未来几年的主航道。
配置方面再分享一个小习惯:每台节点的server.properties我会用一个脚本按模板自动生成,只允许变量部分的差异,避免手改导致的低级错误。另外强烈建议把KAFKA_CLUSTER_ID写进部署文档里保存,集群初始化阶段一旦丢了它,所有节点都得重新格式化,那可真是一场灾难。
这篇内容到这里就结束了。如果你搭建过程中遇到什么问题,欢迎在评论区把日志贴出来一起讨论,我看到了都会回复。