上一篇博客中,我们初步了解了Kafka实质上是一个消息队列,具有异步、解耦、削峰的作用并且在mac环境下安装了Kafka相关环境,具体可以参考Kafka学习笔记(一):Kafka简介与mac下的环境配置。今天我们将以实战的方式深入理解 Kafka 集群的基本组件和专有术语 broker、topic、producer、consumer、partition等。
从上节课的实验,我们了解了 Kafka 的基本架构:一个 producer(生产者)发送消息到 Kafka 集群的某个 topic 中。consumer(消费者)可以消费某个(某几个) topic 中的消息。Kafka 集群由多个 broker 组成。
基本概念
broker
一台服务器上只会安装一个 Kafka 软件,这台服务器就是一个 Kafka Server,此时 Kafka Server 称为 broker。在我们上一篇文章的实验环境中,我们通过修改配置文件的方式实现了一个一台服务器上安装了三个 broker。
topic 和 partition
发布到 Kafka 集群上的消息都属于某一个分类,这个分类称为 topic。topic 存储在 broker 中。一个 topic 包括多个 partition(分区),partition 是物理上的概念。producer 发送的消息存储在 partition 中,每个 partition 可以有多个 replica(副本)。
producer 和 consumer
producer 是用来产生消息的,负责将消息发送到 Kafka broker 的 topic 上,consumer 是用来消费消息的,用于从 Kafka broker 上的 topic 中读取消息。
broker 和 consumer 使用 Zookeeper 管理状态信息,如 offset 信息。上述内容可以用下图表示:
- 上图中展示了 Kafka 相关的 5 个组件:producer、consumer、broker、topic、Zookeeper。
- 上图中展示了一个 broker,broker 中有一个名称为 KafkaTopic 的 Topic,KafkaTopic 中有 3 个 partition ,分别为 partition1 、partition2 、partition3 。
- 消息生产者 producer 将消息发送到 topic 的 partition 中。
- 消息消费者 consumer 从 topic 的 partition 中读取消息。
- consumer 和 broker 的元数据信息保存在 Zookeeper 中。
- 在 topic 中,每一个 partition 对应一个日志文件,partition 是一个有序的、不可变的消息序列。一个消息只能发送到一个 partition 上。
使用Kafka自带脚本进行测试
上一节中我们使用下面的命令创建了第一个topic,下面我们详细介绍一下脚本中参数对应的含义。(我这里使用的是mac系统,linux系统下脚本会有.sh的后缀,另外需要提前启动Kafka集群,启动的命令可以参考上一篇文章)
./kafka-topics --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic myFirstTopic
-
kafka-topics.sh
:Kafka 提供的一个 shell 脚本文件(位于 bin 目录中),用于创建或查看 topic 信息。 -
--create
:shell 脚本的参数,告诉 shell 脚本要创建一个 topic。 -
--zookeeper localhost:2181
:shell 脚本的参数,告诉 shell 脚本 Zookeeper 的地址用于保存 topic 元数据信息。 -
--partitions 1
:shell 脚本参数,告诉 shell 脚本所创建的这个 topic 的 partition 个数为 1。 -
--replication-factor 1
:shell 脚本参数,告诉 shell 脚本每个 partition 的副本数为 1。 -
--topic myFirstTopic
:shell 脚本参数,告诉 shell 脚本创建的 topic 的名称为myFirstTopic
。
接下来,我们创建一个包含 3 个 partition、每个 partition 有 2 个副本的 topic:mySecondTopic
。
命令如下
./kafka-topics --create --zookeeper localhost:2181 --replication-factor 2 --partitions 3 --topic mySecondTopic
查看方法:在 bin
目录下运行命令:
./kafka-topics --zookeeper localhost:2181 --describe --topic mySecondTopic
运行结果如下,
第一行 topic 信息概述:Topic 名称为 mySecondTopic
,partition 数量为 3,副本数为 2,三个 partition 的详细配置信息见下面三行。紧接着三行信息,每一行描述了一个 partition 的信息, leader、replicas 和 ISR 后面的数字对应的是broker-id,leader是负责进行消息读写的broker,副本和Isr参数保证了 kafka 集群的健壮性,保证消息不丢失,保证消息的高吞吐量。
理解 Kafka topic
前面我们创建了两个 topic:myFirstTopic、mySecondTopic。创建 topic 的 shell 命令中用到了 partitions 和 replication-factor 等参数,在这里对 topic 的作用和参数含义再次说明:
- topic:用于划分 Kafka 集群中的消息(Message)的逻辑概念,生产者发送消息,要发送给某个 topic;消费者消费消息,要消费某个(某几个)topic 中的消息。Kafka 集群中的消息都存储在 topic 中。
- Partitions:topic 中的消息是以 partition 分区的形式存储的,注意:partition 是 Kafka 支持扩展和高并发处理的基础。每个 topic 包括 1 个或多个 partition。
- Offset:每个 partition 中的消息都是顺序存储的,每个消息都是有编号的,编号是顺序增长的。这个编号叫 offset,offset 记录了消息在 partition 中的位置。注意:offset 在一个 partition 内是有序的,多个 partition 之间的 offset 是独立存在的。
- Replication:Kafka 支持以 partition 为单位对消息进行冗余备份,每个 Partition 都必须配置至少 1 个 replication。replication-factor 参数指定了 replication 的个数,即 partition 的副本个数。
- Leader replica:在 partition 的多个副本 replication 中,有一个副本叫主副本(即 Leader replica),所有消息消费者和消息生产者的读写请求都由 Leader replica 处理,这么做是为了保证一致性。其他副本叫从副本(即 Follower replica),从副本从主副本处把数据更新同步到本地。
- ISR(全拼为:In-Sync Replica):从副本中,如果从主副本处把数据更新同步到本地了,那么这个从副本处于 ISR 状态(已同步状态),如果没有完全与主副本同步,那么会被从 ISR 中踢出去,处于非同步状态。
在下面的图中,我们可以直观地看到 topic 和 partition 的关系:
上图中,一个 topic 有 3 个 partition,每个 partition 维护着独立的 offset。如 partition 0 中,最先发送到这个 partition 中的消息,offset 为 0,后来的消息 offset 为 1,2,3…依次类推。
列出 Kafka 集群上的所有 topic 并查看 topic 详细信息
依次执行下面的命令,我们可以获得Topic的相关信息
#列出所有的topic名称
./kafka-topics --zookeeper localhost:2181 --list
#列出名称为mySecondTopic的topic的详细信息
./kafka-topics --zookeeper localhost:2181 --describe --topic mySecondTopic
修改 topic 的分区数
现在我们修改 mySecondTopic
这个 topic 的分区数
#注意:shell命令中的关键参数--alter,将partition数量由原来的3改为4
./kafka-topics --zookeeper localhost:2181 --alter --topic mySecondTopic --partitions 4
如果 topic 的 partition 数量增加了,那么消息的分区逻辑或者消息的顺序都会受到影响。而且对于一个 topic 来说,其 partition 的数量,只能增加,不能减少。
删除 topic
现在我们学习删除 topic。由于后面的实验会用到我们创建的 myFirstTopic
和 mySecondTopic
两个 topic,所以在本实验中我们新建一个 topic:myDeleteTopic
,创建方法参见 mySecondTopic
的创建命令。使用下述命令删除 myDeleteTopic
。
#注意:shell命令中的关键参数--delete。
./kafka-topics --zookeeper localhost:2181 --delete --topic myDeleteTopic
我们可以运行如下命令验证topic已经被删除:./kafka-topics --zookeeper localhost:2181 --list
。