kafka基于KRaft工作模式集群部署实战
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
目录
一.kafka和zookeeper的那些事
1.Kafka和ZooKeeper的关系
ZooKeeper 是一个分布式协调服务,常用于管理配置、命名和同步服务。
长期以来,Kafka 使用 ZooKeeper 负责管理集群元数据、控制器选举和消费者组协调等任务理,包括主题、分区信息、ACL(访问控制列表)等。
ZooKeeper 为 Kafka 提供了选主(leader election)、集群成员管理等核心功能,为 Kafka提供了一个可靠的分布式协调服务,使得 Kafka能够在多个节点之间进行有效的通信和管理。
然而,随着 Kafka的发展,其对 ZooKeeper的依赖逐渐显露出一些问题,这些问题也是下面 Kafka去除 Zookeeper的原因。
- kafka 2.8+ 为什么要移除zookeeper组件呢?[kafka 4.0+版本彻底移除了zookeeper组件]
1.复杂性增加
ZooKeeper 是独立于 Kafka 的外部组件,需要单独部署和维护,因此,使用 ZooKeeper 使得 Kafka的运维复杂度大幅提升。
运维团队必须同时管理两个分布式系统(Kafka和 ZooKeeper),这不仅增加了管理成本,也要求运维人员具备更高的技术能力。
2. 性能瓶颈
作为一个协调服务,ZooKeeper 并非专门为高负载场景设计, 因此,随着集群规模扩大,ZooKeeper在处理元数据时的性能问题日益突出。
例如,当分区数量增加时,ZooKeeper需要存储更多的信息,这导致了监听延迟增加,从而影响Kafka的整体性能。
在高负载情况下,ZooKeeper可能成为系统的瓶颈,限制了Kafka的扩展能力。
3. 一致性问题
Kafka 内部的分布式一致性模型与 ZooKeeper 的一致性模型有所不同。由于 ZooKeeper和 Kafka控制器之间的数据同步机制不够高效,可能导致状态不一致,特别是在处理集群扩展或不可用情景时,这种不一致性会影响消息传递的可靠性和系统稳定性。
4.发展自己的生态
Kafka 抛弃 ZooKeeper,我个人觉得最核心的原因是:Kafka生态强大了,需要自立门户,这样就不会被别人卡脖子。
纵观国内外,有很多这样鲜活的例子,当自己弱小时,会先选择使用别家的产品,当自己羽翼丰满时,再选择自建完善自己的生态圈。
2.KAFKA 2.8+引入Kraft模式抛弃ZooKeeper
kafka2.8.0版本引入了基于Raft共识协议的新特性,它允许kafka集群在没有ZooKeeper的情况下运行。
为了剥离和去除ZooKeeper,Kafka引入了自己的亲儿子KRaft(Kafka Raft Metadata Mode)。
KRaft是一个新的元数据管理架构,基于Raft一致性算法实现的一种内置元数据管理方式,旨在替代ZooKeeper的元数据管理功能。
KRaft的优势有以下几点:
简化部署:
Kafka 集群不再依赖外部的 ZooKeeper 集群,简化了部署和运维的复杂性。
KRaft 将所有协调服务嵌入 Kafka 自身,不再依赖外部系统,这样大大简化了部署和管理,因为管理员只需关注 Kafka 集群。
高效的一致性协议:
Raft 是一种简洁且易于理解的一致性算法,易于调试和实现。KRaft 利用 Raft 协议实现了强一致性的元数据管理,优化了复制机制。
提高性能:
由于元数据管理不再依赖 ZooKeeper,Kafka 集群的性能得到了提升,尤其是在元数据读写方面。
增强可扩展性:
KRaft 模式支持更大的集群规模,可以有效地扩展到数百万个分区。
提高元数据操作的扩展性:新的架构允许更多的并发操作,并减少了因为扩展性问题导致的瓶颈,特别是在高负载场景中。
更快的控制器故障转移:
控制器(Controller)的选举和故障转移速度更快,提高了集群的稳定性。
消除 ZooKeeper 作为中间层之后,Kafka 的延迟性能有望得到改善,特别是在涉及选主和元数据更新的场景中。
KRaft模式下,kafka集群中的一些节点被指定为控制器(Controller),它们负责集群的元数据管理和共识服务,所有的元数据都存储在kafka内部的主题中,
而不是ZooKeeper,控制器通过KRaft协议来确保元数据在集群中的准确复制,这种模式使用了基于时间的存储模型,通过定期快照来保证元数据日志不会无限增长。
完全自主:
因为是自家产品,所以产品的架构设计,代码开发都可以自己说了算,未来架构走向完全控制在自己手上。
控制器(Controller)节点的去中心化:
KRaft 模式中,控制器节点由一组 Kafka 服务进程代替,而不是一个独立的 ZooKeeper 集群。
这些节点共同负责管理集群的元数据,通过 Raft 实现数据的一致性。
日志复制和恢复机制:
利用 Raft 的日志复制和状态机应用机制,KRaft 实现了对元数据变更的强一致性支持,这意味着所有控制器节点都能够就集群状态达成共识。
动态集群管理:
KRaft允许动态地向集群中添加或移除节点,而无需手动去ZooKeeper中更新配置,这使得集群管理更为便捷。
3.kafka4.0+版本不支持zookeeper
其实kafka 2.8+版本就支持基于KRaft架构来实现了。从kafka 4.0版本就彻底移除了zookeeper组件。
参考链接:
https://cwiki.apache.org/confluence/display/KAFKA/KIP-500%3A+Replace+ZooKeeper+with+a+Self-Managed+Metadata+Quorum
二.kafka基于KRaft工作模式集群部署实战
1.停止zookeeper集群
[root@elk91 ~]# zkServer.sh stop
[root@elk92 ~]# zkServer.sh stop
[root@elk93 ~]# zkServer.sh stop
温馨提示:
目的是防止大家以为kafka对zookeeper集群的依赖!!!如果您没有部署zookeeper,则可以跳过此步骤哟~
2.修改kafka的配置文件
[root@elk91 ~]# cp /usr/local/kafka_2.13-3.9.1/config/server.properties{,-kraft}
[root@elk91 ~]# vim /usr/local/kafka_2.13-3.9.1/config/server.properties-kraft
# 指的borker的ID
broker.id=66
# 监听地址
advertised.listeners=PLAINTEXT://10.0.0.91:9092
num.network.threads=3
num.io.threads=8
socket.send.buffer.bytes=102400
socket.receive.buffer.bytes=102400
socket.request.max.bytes=104857600
# 指定数据目录
log.dirs=/var/lib/kafka391-kraft
num.partitions=1
num.recovery.threads.per.data.dir=1
offsets.topic.replication.factor=1
transaction.state.log.replication.factor=1
transaction.state.log.min.isr=1
log.retention.hours=168
log.retention.check.interval.ms=300000
group.initial.rebalance.delay.ms=0
# zookeeper的配置请一定要注释掉!!!
# zookeeper.connect=10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181/kafka-v3.9.1
# 指定kafka集群的角色,controller维护集群的角色,broker存储数据的角色。此处我进行了复用。
process.roles=broker,controller
# 配置监听
listeners=PLAINTEXT://:9092,CONTROLLER://:9093
# 定义监听的名称,必须在‘listeners’列表中
controller.listener.names=CONTROLLER
# 配置kafka集群映射列表,注意端口是controller端口
controller.quorum.voters=66@10.0.0.91:9093,77@10.0.0.92:9093,88@10.0.0.93:9093
[root@elk91 ~]#
3.拷贝配置文件到其他节点
[root@elk91 ~]# scp /usr/local/kafka_2.13-3.9.1/config/server.properties-kraft 10.0.0.92:/usr/local/kafka_2.13-3.9.1/config/
[root@elk91 ~]# scp /usr/local/kafka_2.13-3.9.1/config/server.properties-kraft 10.0.0.93:/usr/local/kafka_2.13-3.9.1/config/
4.另外两个节点需要修改配置文件
[root@elk92 ~]# vim /usr/local/kafka_2.13-3.9.1/config/server.properties-kraft
...
broker.id=77
advertised.listeners=PLAINTEXT://10.0.0.92:9092
[root@elk93 ~]# vim /usr/local/kafka_2.13-3.9.1/config/server.properties-kraft
...
broker.id=88
advertised.listeners=PLAINTEXT://10.0.0.93:9092
5.生成UUID
[root@elk91 ~]# kafka-storage.sh random-uuid
gP8Rxn7eTMCcLwhK2sjSlA
[root@elk91 ~]#
6.所有节点初始化集群
[root@elk91 ~]# kafka-storage.sh format -t gP8Rxn7eTMCcLwhK2sjSlA -c /usr/local/kafka_2.13-3.9.1/config/server.properties-kraft
Formatting metadata directory /var/lib/kafka391-kraft with metadata.version 3.9-IV0.
[root@elk91 ~]#
[root@elk91 ~]# ll /var/lib/kafka391-kraft
total 16
drwxr-xr-x 2 root root 4096 Jun 26 16:54 ./
drwxr-xr-x 66 root root 4096 Jun 26 16:54 ../
-rw-r--r-- 1 root root 249 Jun 26 16:54 bootstrap.checkpoint
-rw-r--r-- 1 root root 123 Jun 26 16:54 meta.properties
[root@elk91 ~]#
[root@elk91 ~]# cat /var/lib/kafka391-kraft/meta.properties
#
#Thu Jun 26 16:54:35 CST 2025
cluster.id=gP8Rxn7eTMCcLwhK2sjSlA
directory.id=_Ar3Kwhzoh8sfhm0_KvZKA
node.id=66
version=1
[root@elk91 ~]#
[root@elk92 ~]# kafka-storage.sh format -t gP8Rxn7eTMCcLwhK2sjSlA -c /usr/local/kafka_2.13-3.9.1/config/server.properties-kraft
Formatting metadata directory /var/lib/kafka391-kraft with metadata.version 3.9-IV0.
[root@elk92 ~]#
[root@elk92 ~]# ll /var/lib/kafka391-kraft/
total 16
drwxr-xr-x 2 root root 4096 Jun 26 16:55 ./
drwxr-xr-x 68 root root 4096 Jun 26 16:55 ../
-rw-r--r-- 1 root root 249 Jun 26 16:55 bootstrap.checkpoint
-rw-r--r-- 1 root root 123 Jun 26 16:55 meta.properties
[root@elk92 ~]#
[root@elk92 ~]# cat /var/lib/kafka391-kraft/meta.properties
#
#Thu Jun 26 16:55:26 CST 2025
cluster.id=gP8Rxn7eTMCcLwhK2sjSlA
directory.id=xNPVlmPAVq3W7xrNb_lINQ
node.id=77
version=1
[root@elk92 ~]#
[root@elk93 ~]# kafka-storage.sh format -t gP8Rxn7eTMCcLwhK2sjSlA -c /usr/local/kafka_2.13-3.9.1/config/server.properties-kraft
Formatting metadata directory /var/lib/kafka391-kraft with metadata.version 3.9-IV0.
[root@elk93 ~]#
[root@elk93 ~]# ll /var/lib/kafka391-kraft/
total 16
drwxr-xr-x 2 root root 4096 Jun 26 16:55 ./
drwxr-xr-x 66 root root 4096 Jun 26 16:55 ../
-rw-r--r-- 1 root root 249 Jun 26 16:55 bootstrap.checkpoint
-rw-r--r-- 1 root root 123 Jun 26 16:55 meta.properties
[root@elk93 ~]#
[root@elk93 ~]# cat /var/lib/kafka391-kraft/meta.properties
#
#Thu Jun 26 16:55:56 CST 2025
cluster.id=gP8Rxn7eTMCcLwhK2sjSlA
directory.id=krvCT8b2DepzDUMpuPHaog
node.id=88
version=1
[root@elk93 ~]#
7.后台启动kafka集群
[root@elk91 ~]# kafka-server-start.sh -daemon ${KAFKA_HOME}/config/server.properties-kraft
[root@elk91 ~]#
[root@elk91 ~]# ss -ntl | egrep "9092|9093"
LISTEN 0 50 *:9093 *:*
LISTEN 0 50 *:9092 *:*
[root@elk91 ~]#
[root@elk92 ~]# kafka-server-start.sh -daemon ${KAFKA_HOME}/config/server.properties-kraft
[root@elk92 ~]# ss -ntl | egrep "9092|9093"
LISTEN 0 50 *:9092 *:*
LISTEN 0 50 *:9093 *:*
[root@elk92 ~]#
[root@elk93 ~]# kafka-server-start.sh -daemon ${KAFKA_HOME}/config/server.properties-kraft
[root@elk93 ~]# ss -ntl | egrep "9092|9093"
LISTEN 0 50 *:9093 *:*
LISTEN 0 50 *:9092 *:*
[root@elk93 ~]#
8.测试验证
8.1 启动生产者
[root@elk91 ~]# kafka-console-producer.sh --bootstrap-server 10.0.0.92:9092 --topic yinzhengjie-kafka
>https://www.cnblogs.com/yinzhengjie
[2025-06-26 17:00:53,052] WARN [Producer clientId=console-producer] The metadata response from the cluster reported a recoverable issue with correlation id 7 : {yinzhengjie-kafka=UNKNOWN_TOPIC_OR_PARTITION} (org.apache.kafka.clients.NetworkClient)
[2025-06-26 17:00:53,168] WARN [Producer clientId=console-producer] The metadata response from the cluster reported a recoverable issue with correlation id 8 : {yinzhengjie-kafka=UNKNOWN_TOPIC_OR_PARTITION} (org.apache.kafka.clients.NetworkClient)
>https://space.bilibili.com/600805398/lists
>
8.2 启动消费者
[root@elk93 ~]# kafka-console-consumer.sh --bootstrap-server 10.0.0.93:9092 --topic yinzhengjie-kafka --from-beginning
https://www.cnblogs.com/yinzhengjie
https://space.bilibili.com/600805398/lists
三.课后作业
- 使用ansible一键部署zookeeper集群,kafka集群;
- 调研RabbitMQ集群部署并启动生产者和消费者测试案例;
本文来自博客园,作者:尹正杰,转载请注明原文链接:https://www.cnblogs.com/yinzhengjie/p/18940962,个人微信: "JasonYin2020"(添加时请备注来源及意图备注,有偿付费)
当你的才华还撑不起你的野心的时候,你就应该静下心来学习。当你的能力还驾驭不了你的目标的时候,你就应该沉下心来历练。问问自己,想要怎样的人生。