只需三步,使用 KRaft 建立多节点 Kafka 集群

2024-05-29 17:04

本文主要是介绍只需三步,使用 KRaft 建立多节点 Kafka 集群,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Apache Kafka是一个用 Java 编写的开源分布式事件和流处理平台,用于处理要求苛刻的实时数据馈送。它本质上是可扩展的,具有高吞吐量和高可用性。其设计也具有容错性,每个集群可支持数百个节点。

在本教程中,你将创建一个 Kafka 集群,使用 KRaft共识协议的 Kafka 集群。你将学习如何配置节点成为集群的一部分,并观察主题分区是如何分配给不同节点的。你还将学习如何将主题分配给集群中的特定代理。

让我们开始吧!

准备工作

为了你能顺利跟上本教程的步骤,你需要这些:

  • 三个可用的 Droplets,至少需要 4GB 内存以及 2 个 CPU。如果是 Ubuntu 服务器,请按照 Ubuntu 初始服务器设置获取设置说明,或参照教程在 DigitalOcean Droplet 云主机上创建 Ubuntu 服务器。

  • 一个完全注册的域名,带有指向三个 Droplets的三个子域。本教程将把它们分别称为 kafkaX.your_domain。你可以在 Namecheap 购买域名,在 Freenom 上免费获取一个,或者也可以使用你选择的域名注册商。

  • 在 Droplets 上安装和配置 Apache Kafka。有关安装说明,你可以按照 Kafka 简介教程配置。你只需完成第一步 第二步

第一步:配置 Kafka 节点

在这一步中,你将配置作为准备工作

一部分创建的三个 Kafka 服务器,使其成为同一个 KRaft 集群的一部分。有了 KRaft,节点本身就可以组织和执行管理任务,而无需依赖 Apache ZooKeeper。

配置第一个节点

你将先配置第一个节点。首先,运行以下命令停止第一个 Droplet 上的服务:

sudo systemctl stop kafka

接下来,以用户 kafka 的身份,导航到 Kafka 所在的目录,并通过运行打开其配置文件进行编辑:

vi /config/kraft/server.properties

找出以下几行:

...
# The role of this server. Setting this puts us in KRaft mode
process.roles=broker,controller# The node id associated with this instance's roles
node.id=1# The connect string for the controller quorum
controller.quorum.voters=1@localhost:9092
...

这三个参数将 Kafka 节点同时配置为代理和控制器,这意味着它将接收和消费数据(代理)并执行管理任务(控制器)。这种分离在大型部署中非常有用,可以将控制器分开,以提高效率和冗余。

node.id 指定了节点在群集中的 ID。这是第一个节点,所以它的 ID 是 1,因此第二个和第三个节点的 ID 将分别为 23

controller.quorum.voters 将节点 ID 映射到它们各自的地址和端口,以便通信。这里将指定所有集群节点的地址,以便每个节点都能知道其他节点。修改该行如下(config/kraft/server.properties):

...
controller.quorum.voters=1@kafka1.your_domain:9093,2@kafka2.your_domain:9093,3@kafka3.your_domain:9093
...

在此,你将列出集群中的所有三个节点及其各自的 ID。记住将 your_domain 替换为你在准备工作中设置的域名地址。

接下来,在文件中找到以下几行:

...
listeners=PLAINTEXT://:9092,CONTROLLER://:9093# Name of listener used for communication between brokers.
inter.broker.listener.name=PLAINTEXT# Listener name, hostname and port the broker will advertise to clients.
# If not set, it uses the value for "listeners".
advertised.listeners=PLAINTEXT://localhost:9092
...

listeners 定义了 Kafka 节点监听的地址,而 advertised.listeners 则指定了将传递给客户端以连接到节点的地址。这让你可以为客户端指定它应该使用的实际地址的子集。

修改以下代码行,用实际域名替换其中的 your_domain

...
listeners=PLAINTEXT://kafka1.your_domain:9092,CONTROLLER://kafka1.your_domain:9093# Name of listener used for communication between brokers.
inter.broker.listener.name=PLAINTEXT# Listener name, hostname and port the broker will advertise to clients.
# If not set, it uses the value for "listeners".
advertised.listeners=PLAINTEXT://kafka1.your_domain:9092
...

由于该节点将位于一个集群中,因此你已明确将地址指向了运行该节点的 Droplet。

然后,找到 num.partitions设置:

...
# The default number of log partitions per topic. More partitions allow greater
# parallelism for consumption, but this will also result in more files across
# the brokers.
num.partitions=1
...

正如注释所述,这配里置了每个新主题的默认分区数量。 由于你有三个节点,因此将其设置为 2 的倍数:

...
num.partitions=6
...

这里的值为 6 可确保每个节点默认拥有两个主题分区。

下一步是配置内部主题的复制因子,它将保留消费者偏移和事务状态。找到以下几行:

...
offsets.topic.replication.factor=1
transaction.state.log.replication.factor=1
...

将它们设置为以下值:

...
offsets.topic.replication.factor=2
transaction.state.log.replication.factor=2
...

在这里,你需要指定至少两个节点的内部元数据必须同步。完成后,保存并关闭文件。

设置默认分区号后,必须重新初始化日志存储。首先,运行以下命令删除现有日志文件:

rm -rf /home/kafka/kafka-logs/*

然后,生成一个新的群集 ID 并将其存储为环境变量:

KAFKA_CLUSTER_ID="$(bin/kafka-storage.sh random-uuid)"

在终端显示:

echo $KAFKA_CLUSTER_ID

输出将是集群 ID:


Mjj4bch9Q3-B0TEXv8_zPg

请注意该值;配置第二个和第三个节点时会用到它。

最后,运行以下命令生成日志存储:

./bin/kafka-storage.sh format -t $KAFKA_CLUSTER_ID -c config/kraft/server.properties

输出结果与此类似:

...
Formatting /home/kafka/kafka-logs with metadata.version 3.7-IV4.

配置第二和第三节点

其他节点的配置与第一个节点的配置非常相似。注意也要更新 node.id

...
node.id=node_number
...

第二个和第三个节点的值分别为23,并为 listenersadvertised.listeners 设置地址。

重新生成日志存储时,重复使用第一个节点的群集 ID:

KAFKA_CLUSTER_ID="your_cluster_id"

完成后,在所有三个节点上运行 Kafka 服务:

sudo systemctl start kafka

在这一步中,你已将三个 Kafka 节点配置为 KRaft 集群的一部分。你将创建一个主题,并在集群上生产和消费消息。

第二步:连接至群集

在这一步中,你将使用 Kafka 捆绑的 shell 脚本连接到 Kafka 集群。你还将创建一个主题,并尝试从集群中生产和消费数据。然后,你将使其中一个节点宕机,并观察 Kafka 如何减轻损失。

Kafka 提供了kafka-metadata-quorum.sh 脚本,用于显示有关集群及其成员的信息。运行以下命令执行该脚本:

./bin/kafka-metadata-quorum.sh --bootstrap-controller kafka1.your_domain:9093 describe --status

你通过 9093 端口连接到其中一个节点,这是控制器的端点(但不是代理的端点)。切记将 kafka1.your_domain 替换为指向其中一个 Kafka 节点的域。

输出结果为:

ClusterId:              G3TeIZoeTSCvG2YOWvPE2w
LeaderId:               3
LeaderEpoch:            2
HighWatermark:          383
MaxFollowerLag:         0
MaxFollowerLagTimeMs:   55
CurrentVoters:          [1,2,3]
CurrentObservers:       []

脚本列出了集群状态的基本信息。在显示的输出中,你可以看到节点 3 被选为领导者,所有三个节点([1,2,3])都在投票池中,并同意这一决定。

运行并创建一个名为 first-topic 的主题:

./bin/kafka-topics.sh --create --topic first-topic --bootstrap-server kafka1.your_domain:9092 --replication-factor 2

输出结果将是:

Created topic first-topic.

然后,运行 kafka-topics.sh 脚本,查看分区在节点上的排列情况:

./bin/kafka-topics.sh --describe --bootstrap-server kafka1.your_domain:9092 --topic first-topic

将复制因子设置为 2 可确保主题至少在两个节点上可用。

输出结果与此类似:

Topic: first-topic      TopicId: 4kVImoFNTQeyk3r2zQbdvw PartitionCount: 6       ReplicationFactor: 2    Configs: segment.bytes=1073741824Topic: first-topic      Partition: 0    Leader: 3       Replicas: 3,1   Isr: 3,1Topic: first-topic      Partition: 1    Leader: 1       Replicas: 1,2   Isr: 1,2Topic: first-topic      Partition: 2    Leader: 2       Replicas: 2,3   Isr: 2,3Topic: first-topic      Partition: 3    Leader: 1       Replicas: 1,3   Isr: 1,3Topic: first-topic      Partition: 4    Leader: 3       Replicas: 3,2   Isr: 3,2Topic: first-topic      Partition: 5    Leader: 2       Replicas: 2,1   Isr: 2,1

可以看到,每个分区都有一个领导者、两个副本和两个同步副本集(ISR)。分区领导者是向客户端提供分区数据的代理节点,而副本节点只保存副本。默认情况下,如果一个副本节点在过去的十秒钟内赶上了领导者,那么它就被认为是 ISR。这个时间间隔可根据每个主题进行配置。

创建主题后,就可以使用 kafka-console-producer.sh 脚本生成消息了。运行以下命令启动生产者:

./bin/kafka-console-producer.sh --topic first-topic --bootstrap-server kafka1.your_domain:9092

你将看到一个空提示:

>

生产者正等着你输入文字信息。输入 test 并按 ENTER 键。提示如下

>Hello World!
>

生产者现在正在等待下一条消息,这意味着上一条消息已成功传送到 Kafka。你可以输入任意数量的信息进行测试。要退出生产者,请按 CTRL+C

你需要一个消耗者来回读主题中的消息。Kafka 提供了一个简单的消耗者,名为 kafka-console-consumer.sh。通过执行以下命令运行:

./bin/kafka-console-consumer.sh --topic first-topic --from-beginning --bootstrap-server kafka1.your_domain:9092

你将看到从主题中读取的信息:

Hello World!
...

模拟节点故障

在第三个 Kafka 节点上,运行以下命令停止服务:

sudo systemctl stop kafka

然后,运行描述主题:

./bin/kafka-topics.sh --describe --bootstrap-server kafka1.your_domain:9092 --topic first-topic

输出结果与此类似:

Topic: first-topic      TopicId: 4kVImoFNTQeyk3r2zQbdvw PartitionCount: 6       ReplicationFactor: 2    Configs: segment.bytes=1073741824Topic: first-topic      Partition: 0    Leader: 1       Replicas: 3,1   Isr: 1Topic: first-topic      Partition: 1    Leader: 1       Replicas: 1,2   Isr: 1,2Topic: first-topic      Partition: 2    Leader: 2       Replicas: 2,3   Isr: 2Topic: first-topic      Partition: 3    Leader: 1       Replicas: 1,3   Isr: 1Topic: first-topic      Partition: 4    Leader: 2       Replicas: 3,2   Isr: 2Topic: first-topic      Partition: 5    Leader: 2       Replicas: 2,1   Isr: 2,1

尽管节点 3 已被列为副本,但由于它不可用,所以 ISR 集中缺少它。一旦重新加入群集,它将与其他节点同步,并尝试重新获得之前的位置。

再试着阅读一下 first-topic 中的信息:

./bin/kafka-console-consumer.sh --topic first-topic --from-beginning --bootstrap-server kafka1.your_domain:9092

你会发现它们可以像往常一样访问:

Hello World!
...

由于复制的存在,前两个节点会接管并为消费者提供服务。现在,你可以在第三台服务器上启动 Kafka:

sudo systemctl start kafka

在这一步中,你已经看到 Kafka 如何缓解集群中节点的不可用性。现在,你将学习如何从容地从集群中排除一个节点。

第三步 :在节点之间迁移数据

在本步骤中,你将学习如何在 Kafka 集群的节点之间迁移主题。在向包含主题的现有集群添加节点时,Kafka 不会自动将任何分区转移到集群中,而你可能希望这样做。这对于删除节点也很有用,因为现有分区不会自动转移到剩余的节点上。

Kafka 提供了一个名为 kafka-reassign-partitions.sh 的脚本,它可以生成、执行和验证转换计划。你将使用它创建一个计划,将 first-topic 的分区移动到前两个节点。

首先,你需要定义要移动的主题。脚本接受一个包含主题定义的 JSON 文件,因此请创建并打开该文件进行编辑:

vi topics-to-move.json

添加以下几行 :

{"topics": [{"topic": "first-topic"}],"version": 1
}

topic下,定义一个引用first-topic的对象。完成后,保存并关闭文件。

运行以下命令生成迁移计划,将 kafka1.your_domain 替换为指向其中一个 Kafka 节点的域:

./bin/kafka-reassign-partitions.sh --bootstrap-server kafka1.your_domain:9092 --topics-to-move-json-file topics-to-move.json --broker-list "1,2" --generate

--broker-list 中输入 "1,2",表示目标broker的 ID。

输出结果与此类似:

Current partition replica assignment
{"version":1,"partitions":[{"topic":"first-topic","partition":0,"replicas":[3,1],"log_dirs":["any","any"]},{"topic":"first-topic","partition":1,"replicas":[1,2],"log_dirs":["any","any"]},{"topic":"first-topic","partition":2,"replicas":[2,3],"log_dirs":["any","any"]},{"topic":"first-topic","partition":3,"replicas":[1,3],"log_dirs":["any","any"]},{"topic":"first-topic","partition":4,"replicas":[3,2],"log_dirs":["any","any"]},{"topic":"first-topic","partition":5,"replicas":[2,1],"log_dirs":["any","any"]}]}Proposed partition reassignment configuration
{"version":1,"partitions":[{"topic":"first-topic","partition":0,"replicas":[2,1],"log_dirs":["any","any"]},{"topic":"first-topic","partition":1,"replicas":[1,2],"log_dirs":["any","any"]},{"topic":"first-topic","partition":2,"replicas":[2,1],"log_dirs":["any","any"]},{"topic":"first-topic","partition":3,"replicas":[1,2],"log_dirs":["any","any"]},{"topic":"first-topic","partition":4,"replicas":[2,1],"log_dirs":["any","any"]},{"topic":"first-topic","partition":5,"replicas":[1,2],"log_dirs":["any","any"]}]}

脚本总共生成了两个计划,分别描述了当前和建议的分区布局。如果以后需要恢复更改,我们会提供第一个计划。请注意第二个计划,它将保存在一个名为 migration-plan.json 的单独文件中。创建并打开该文件进行编辑:

vi migration-plan.json

添加第二个执行计划,在migration-plan.json 中输入:

{"version":1,"partitions":[{"topic":"first-topic","partition":0,"replicas":[2,1],"log_dirs":["any","any"]},{"topic":"first-topic","partition":1,"replicas":[1,2],"log_dirs":["any","any"]},{"topic":"first-topic","partition":2,"replicas":[2,1],"log_dirs":["any","any"]},{"topic":"first-topic","partition":3,"replicas":[1,2],"log_dirs":["any","any"]},{"topic":"first-topic","partition":4,"replicas":[2,1],"log_dirs":["any","any"]},{"topic":"first-topic","partition":5,"replicas":[1,2],"log_dirs":["any","any"]}]}

保存并关闭文件。然后,运行以下命令执行该文件:

./bin/kafka-reassign-partitions.sh --bootstrap-server kafka1.your_domain:9092 --reassignment-json-file migration-plan.json --execute

输出结果将是

Current partition replica assignment{"version":1,"partitions":[{"topic":"first-topic","partition":0,"replicas":[3,1],"log_dirs":["any","any"]},{"topic":"first-topic","partition":1,"replicas":[1,2],"log_dirs":["any","any"]},{"topic":"first-topic","partition":2,"replicas":[2,3],"log_dirs":["any","any"]},{"topic":"first-topic","partition":3,"replicas":[1,3],"log_dirs":["any","any"]},{"topic":"first-topic","partition":4,"replicas":[3,2],"log_dirs":["any","any"]},{"topic":"first-topic","partition":5,"replicas":[2,1],"log_dirs":["any","any"]}]}Save this to use as the --reassignment-json-file option during rollback
Successfully started partition reassignments for first-topic-0,first-topic-1,first-topic-2,first-topic-3,first-topic-4,first-topic-5

脚本指出迁移已经开始。要查看迁移的进度,请使用 --verify 代替:

./bin/kafka-reassign-partitions.sh --bootstrap-server kafka1.your_domain:9092 --reassignment-json-file migration-plan.json --verify

一段时间后,输出结果将与此相似:

Status of partition reassignment:
Reassignment of partition first-topic-0 is completed.
Reassignment of partition first-topic-1 is completed.
Reassignment of partition first-topic-2 is completed.
Reassignment of partition first-topic-3 is completed.
Reassignment of partition first-topic-4 is completed.
Reassignment of partition first-topic-5 is completed.Clearing broker-level throttles on brokers 1,2,3
Clearing topic-level throttles on topic first-topic

现在你可以描述 first-topic,以验证代理 3 上没有分区:

./bin/kafka-topics.sh --describe --bootstrap-server kafka1.your_domain:9092 --topic first-topic

输出结果如下

Topic: first-topic      TopicId: 4kVImoFNTQeyk3r2zQbdvw PartitionCount: 6       ReplicationFactor: 2    Configs: segment.bytes=1073741824Topic: first-topic      Partition: 0    Leader: 2       Replicas: 2,1   Isr: 1,2Topic: first-topic      Partition: 1    Leader: 1       Replicas: 1,2   Isr: 1,2Topic: first-topic      Partition: 2    Leader: 2       Replicas: 2,1   Isr: 2,1Topic: first-topic      Partition: 3    Leader: 1       Replicas: 1,2   Isr: 1,2Topic: first-topic      Partition: 4    Leader: 2       Replicas: 2,1   Isr: 2,1Topic: first-topic      Partition: 5    Leader: 1       Replicas: 1,2   Isr: 2,1

只有broker 12 作为副本和 ISR 存在,这意味着迁移成功。

在本步骤中,你已制定了将第一个主题从代理 3 迁移到其余主题的迁移计划,并学会了如何验证迁移是否顺利进行。

结论

你现在有了一个 Kafka 集群,它由三个节点组成,使用 KRaft 协议进行通信。你还学会了如何检查集群和分区布局。你已经通过关闭一个节点并从一个主题读取数据来测试集群的冗余性。最后,你还学会了如何将主题重新分配给集群中的节点。

最后,欢迎了解 DigitalOcean 托管 Kafka 数据库服务,DigitalOcean 的 Kafka 支持横向扩展,并且支持用户对 Kafka 自定义指标进行后续的数据监控与分析。如需了解更多 DigitalOcean 云服务的数据产品或其它技术产品,可访问 DigitalOcean 中国区独家战略合作伙伴卓普云的官网。

这篇关于只需三步,使用 KRaft 建立多节点 Kafka 集群的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1014118

相关文章

使用Sentinel自定义返回和实现区分来源方式

《使用Sentinel自定义返回和实现区分来源方式》:本文主要介绍使用Sentinel自定义返回和实现区分来源方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Sentinel自定义返回和实现区分来源1. 自定义错误返回2. 实现区分来源总结Sentinel自定

Pandas使用SQLite3实战

《Pandas使用SQLite3实战》本文主要介绍了Pandas使用SQLite3实战,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录1 环境准备2 从 SQLite3VlfrWQzgt 读取数据到 DataFrame基础用法:读

JSON Web Token在登陆中的使用过程

《JSONWebToken在登陆中的使用过程》:本文主要介绍JSONWebToken在登陆中的使用过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录JWT 介绍微服务架构中的 JWT 使用结合微服务网关的 JWT 验证1. 用户登录,生成 JWT2. 自定义过滤

Java中StopWatch的使用示例详解

《Java中StopWatch的使用示例详解》stopWatch是org.springframework.util包下的一个工具类,使用它可直观的输出代码执行耗时,以及执行时间百分比,这篇文章主要介绍... 目录stopWatch 是org.springframework.util 包下的一个工具类,使用它

Java使用Curator进行ZooKeeper操作的详细教程

《Java使用Curator进行ZooKeeper操作的详细教程》ApacheCurator是一个基于ZooKeeper的Java客户端库,它极大地简化了使用ZooKeeper的开发工作,在分布式系统... 目录1、简述2、核心功能2.1 CuratorFramework2.2 Recipes3、示例实践3

springboot security使用jwt认证方式

《springbootsecurity使用jwt认证方式》:本文主要介绍springbootsecurity使用jwt认证方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录前言代码示例依赖定义mapper定义用户信息的实体beansecurity相关的类提供登录接口测试提供一

go中空接口的具体使用

《go中空接口的具体使用》空接口是一种特殊的接口类型,它不包含任何方法,本文主要介绍了go中空接口的具体使用,具有一定的参考价值,感兴趣的可以了解一下... 目录接口-空接口1. 什么是空接口?2. 如何使用空接口?第一,第二,第三,3. 空接口几个要注意的坑坑1:坑2:坑3:接口-空接口1. 什么是空接

springboot security快速使用示例详解

《springbootsecurity快速使用示例详解》:本文主要介绍springbootsecurity快速使用示例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录创www.chinasem.cn建spring boot项目生成脚手架配置依赖接口示例代码项目结构启用s

Python如何使用__slots__实现节省内存和性能优化

《Python如何使用__slots__实现节省内存和性能优化》你有想过,一个小小的__slots__能让你的Python类内存消耗直接减半吗,没错,今天咱们要聊的就是这个让人眼前一亮的技巧,感兴趣的... 目录背景:内存吃得满满的类__slots__:你的内存管理小助手举个大概的例子:看看效果如何?1.

java中使用POI生成Excel并导出过程

《java中使用POI生成Excel并导出过程》:本文主要介绍java中使用POI生成Excel并导出过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录需求说明及实现方式需求完成通用代码版本1版本2结果展示type参数为atype参数为b总结注:本文章中代码均为