了解 Kafka 主题和分区

Understanding Kafka Topics and Partitions

我开始学习Kafka,在阅读过程中,我想到了一些问题:

  1. 当生产者生产消息时 - 它会指定要将消息发送到的 topic,对吗?它关心分区吗?

  2. 当订阅者是 运行 - 它是否指定其组 ID,以便它可以成为同一主题的消费者集群的一部分,或者这组消费者是多个主题的一部分有兴趣吗?

  3. 是每个消费者组在broker上有一个对应的分区还是每个消费者都有一个?

  4. 分区是由代理创建的,因此消费者不关心吗?

  5. 由于这是一个队列,每个分区都有一个偏移量,消费者是否有责任指定它想要读取哪些消息?它需要保存它的状态吗?

  6. 从队列中删除消息后会发生什么? - 比如保留了3个小时,然后时间过去了,两边offset是怎么处理的?

让我们按顺序来:)

1 - When a producer is producing a message - It will specify the topic it wants to send the message to, is that right? Does it care about partitions?

默认情况下,生产者不关心分区。您可以选择使用自定义分区程序来获得更好的控制,但这完全是可选的。


2 - When a subscriber is running - Does it specify its group id so that it can be part of a cluster of consumers of the same topic or several topics that this group of consumers is interested in?

是的,消费者加入(或创建,如果他们是单独的)消费者组来分担负载。同一组中的两个消费者永远不会收到相同的消息。


3 - Does each consumer group have a corresponding partition on the broker or does each consumer have one?

都没有。在两种情况下,消费者组中的所有消费者都被分配了一组分区:同一组中没有两个消费者有任何共同的分区 - 并且整个消费者组被分配给每个现有分区。


4 - Are the partitions created by the broker, therefore not a concern for the consumers?

他们不是,但是你可以从 3 中看到,拥有比现有分区更多的消费者是完全没有用的,所以这是你消费的最大并行度级别。


5 - Since this is a queue with an offset for each partition, is it responsibility of the consumer to specify which messages it wants to read? Does it need to save its state?

是的,消费者为每个分区的每个主题保存一个偏移量。这完全由 Kafka 处理,不用担心。


6 - What happens when a message is deleted from the queue? - For example: The retention was for 3 hours, then the time passes, how is the offset being handled on both sides?

如果消费者曾经请求过代理上分区不可用的偏移量(例如,由于删除),它会进入错误模式,并最终将此分区的自身重置为最新或最旧的消息可用(取决于 auto.offset.reset 配置值),然后继续工作。

Kafka 使用 Topic 概念来为消息流带来秩序。

为了平衡负载,一个主题可能会被分成多个分区并跨代理复制。

分区是有序的、不可变的消息序列,不断附加,即提交日志。

分区中的消息有一个连续的 ID 号,用于唯一标识分区中的每条消息。

分区允许主题的日志扩展到超过适合单个服务器(代理)的大小,并充当并行单元。

主题的分区分布在 Kafka 集群中的代理上,每个代理处理数据并请求共享分区。

每个分区都在可配置数量的代理之间进行复制,以确保容错。

本文解释得很好:http://codeflex.co/what-is-apache-kafka/

This post already has answers, but I am adding my view with a few pictures from Kafka Definitive Guide

Before answering the questions, let's look at an overview of producer components:

1. When a producer is producing a message - It will specify the topic it wants to send the message to, is that right? Does it care about partitions?

生产者将决定目标分区放置任何消息,具体取决于:

  • 分区 ID,如果它在消息中指定
  • key % num partitions,如果没有提到分区id
  • 如果分区ID消息键在消息中均不可用,则循环法表示只有值可用

2. When a subscriber is running - Does it specify its group id so that it can be part of a cluster of consumers of the same topic or several topics that this group of consumers is interested in?

你应该总是配置 group.id 除非你使用简单的赋值 API 并且你不需要在 Kafka 中存储偏移量。它不会成为任何组的一部分。 source

3. Does each consumer group have a corresponding partition on the broker or does each consumer have one?

在一个消费者组中,每个分区只会由一个消费者处理。这些是可能的情况

  • 消费者数量少于个主题分区数然后多个分区可以分配给组中的一个消费者
  • 消费者数量与主题分区数量相同,那么分区和消费者映射可以如下所示,
  • consumer个数大于个topic分区数,那么partition和consumer mapping如下图,无效,查看Consumer 5

4. As the partitions created by the broker, therefore not a concern for the consumers?

消费者应该知道分区的数量,正如问题 3 中所讨论的那样。

5. Since this is a queue with an offset for each partition, is it the responsibility of the consumer to specify which messages it wants to read? Does it need to save its state?

Kafka(具体来说 Group Coordinator)通过向内部 [=100= 生成消息来处理偏移状态] 主题,此行为也可以通过将 enable.auto.commit 设置为 false 来配置为手动。在这种情况下,consumer.commitSync()consumer.commitAsync() 可能有助于管理偏移量。

有关小组协调员的更多信息

  1. 它是集群中从 Kafka 服务器端选出的代理之一。
  2. 消费者与组协调器交互以获取偏移量提交和获取请求。
  3. 消费者向组协调器发送定期心跳。

6. What happens when a message is deleted from the queue? - For example, The retention was for 3 hours, then the time passes, how is the offset being handled on both sides?

如果任何消费者在保留期后启动,消息将按照 auto.offset.reset 配置使用,可能是 latest/earliest。从技术上讲,它是 latest(开始处理新消息),因为到那时所有消息都已过期,并且 retention 是主题级配置。

  1. 生产者在生产消息时 - 它会指定要将消息发送到的主题,对吗?它关心分区吗?

是的,制作人确实指定了主题

producer.send(new ProducerRecord<byte[],byte[]>(topic,  partition, key1, value1) , callback);

Kafka 集群中的分区越多,吞吐量就越高。选择分区数量的粗略公式是基于吞吐量。您测量在生产(称为 p)和消费(称为 c)的单个分区上可以实现的吞吐量。


  1. 当订阅者是 运行 - 它是否指定其组 ID,以便它可以成为同一主题的消费者集群的一部分或这组消费者感兴趣的多个主题?

当构建了 Kafka 消费者并且 group.id 尚不存在(即没有现有的消费者属于该组)时,将自动创建消费者组。 如果一个群组中的所有消费者都离开该群组,则该群组将自动销毁。


  1. 是每个消费者组在 broker 上都有对应的分区还是每个消费者都有一个?

每个消费者组分配一个分区,多个消费者组可以访问一个分区,但属于一个消费者组的2个消费者不能分配同一个分区,因为消费者在一个组中顺序消费消息,如果多个消费者来自一个单个组从同一分区消费消息,然后序列可能会丢失,而逻辑上独立的组可以从同一分区消费。


  1. 分区是由代理创建的,因此消费者不关心吗?

经纪人已经有了分区。 每个代理最多有 4,000 个分区,每个集群最多有 200,000 个分区。

每当消费者进入或离开消费者组时,代理会重新平衡消费者之间的分区,这意味着 Kafka 会根据每个应用程序实例的分区数量为您处理负载平衡。

在将分区分配给消费者之前,Kafka 会首先检查是否存在具有给定组 ID 的现有消费者。 当没有具有给定 group-id 的现有消费者时,它将将该主题的所有分区分配给这个新消费者。 当已经有两个消费者具有给定的 group-id 并且第三个消费者想要使用相同的 group-id 进行消费时。它将在所有三个消费者之间平均分配分区。同一组 ID 的两个消费者不会被分配到同一分区 source


  1. 由于这是一个队列,每个分区都有一个偏移量,消费者是否有责任指定它想要读取哪些消息?它需要保存它的状态吗?

Offset 由 Kafka 内部处理。当前偏移量是指向 Kafka 在最近一次轮询中已经发送给消费者的最后一条记录的指针。因此,由于当前的偏移量,消费者不会两次获得相同的记录。 不需要专门指定


  1. 从队列中删除消息后会发生什么? - 例如保留了3个小时,然后时间过去了,两边的offset是怎么处理的?

它会根据需要自动重新配置自己。它应该会报错。