主题、分区和键

Posted

技术标签:

【中文标题】主题、分区和键【英文标题】:Topics, partitions and keys 【发布时间】:2016-09-27 11:20:10 【问题描述】:

我正在寻找有关该主题的一些说明。 在 Kafka 文档中,我发现以下内容:

Kafka 仅提供分区内消息的总顺序,而不是主题中不同分区之间的总顺序。对于大多数应用程序来说,按分区排序与按键分区数据的能力相结合就足够了。但是,如果您需要对消息进行总排序,这可以通过只有一个分区的主题来实现,尽管这意味着每个消费者组只有一个消费者进程。

所以这是我的问题:

    这是否意味着如果我希望有超过 1 个消费者(来自同一组)从一个主题读取我需要有超过 1 个分区?

    这是否意味着我需要与同一组的消费者数量相同的分区数量?

    一个分区可以读取多少个消费者?

还有一些关于 API 的键和分区之间关系的问题。我只查看了 .net API(尤其是来自 MS 的 API),但看起来像是模仿 Java API。 我看到使用生产者向主题发送消息时有一个关键参数。但是当消费者从一个主题中读取时,会有一个分区号。

    分区如何编号?从 0 还是 1 开始? 键和分区之间究竟有什么关系? 据我了解,键上的某些功能将确定一个分区。对吗? 如果我在一个主题中有 2 个分区,并且希望某些特定消息转到一个分区,而其他消息转到另一个分区,我应该为一个特定分区使用特定键,而将其余的用于另一个分区? 如果我有 3 个分区和一种类型的消息到一个特定的分区,其余的到另外 2 个呢? 一般而言,我如何将消息发送到特定分区以便让消费者知道从哪里读取? 还是我最好处理多个主题?

提前致谢。

【问题讨论】:

【参考方案1】:

分区增加了 Kafka 主题的并行度。任意数量的消费者/生产者可以使用相同的分区。它由应用层定义协议。卡夫卡保证交货。关于 API,您可能需要查看 Java 文档,因为它们可能更完整。根据我的经验:

    分区从 0 开始 可以使用密钥将消息发送到同一分区。例如 hash(key)%num_partition。该逻辑可插入到 Producer。 https://kafka.apache.org/090/javadoc/index.html?org/apache/kafka/clients/producer/Partitioner.html 是的。但请注意不要以某些会导致“专用”分区的键结束。为此,您可能需要专门的主题。例如控制主题和数据主题 这似乎和 3 是同一个问题。 我认为消费者不应该对基于分区的数据做出假设。典型的方法是让消费者组可以从一个主题的多个分区中读取。如果您想拥有专用频道,最好(更安全/可维护)使用单独的主题。

【讨论】:

【参考方案2】:

这是否意味着如果我想拥有超过 1 个消费者(来自同一 组)从一个主题读取我需要超过 1 个分区?

我们来看看kafka的以下属性:

每个分区只被组中的一个消费者消费 组中的一个消费者可以消费多个分区 组中的消费者进程数必须为

借助这些属性,kafka 能够巧妙地通过消费者进程池同时提供 ordering guaranteesload balancing

要回答你的问题,是的,在同一个组的上下文中,如果你想拥有N consumers,你必须拥有at least N partitions

这是否意味着我需要与消费者数量相同的分区数量 同一组?

我想这在第一个答案中已经解释过了。

一个分区可以读取多少个消费者?

可以从一个分区读取的number of consumers 始终等于订阅该主题的number of consumer groups

关于 API 的键和分区之间的关系

首先,我们必须了解producer负责选择将哪条记录分配给主题内的哪个分区。

现在,让我们看看生产者是如何做到的。首先,让我们看看ProducerRecord.java 的类定义:

public class ProducerRecord<K, V> 

    private final String topic;
    private final Integer partition;
    private final Headers headers;
    private final K key;
    private final V value;
    private final Long timestamp;


这里,我们必须从类中理解的字段是partition

来自ProducerRecord docs,

如果指定了有效的partition number,则发送记录时将使用partition 如果未指定分区但存在key,则将使用hash of the key 选择分区。 如果keypartition 都不存在,则将在round-robin fashion 中分配一个分区。

【讨论】:

发送分区消息的规则很好。? 感谢您解释键和分区号之间的区别。在尝试使用 kafka-console-producer 工具时,这让我大吃一惊。消息没有出现在我认为我指定的分区中,结果证明是键值。 两个键可以有相同的分区吗?不同key的消息如何存储在同一个partition中? 因此,如果我们指定一个与我们的对象相对应的键(例如客户编号),我们会得到一致的对象分配给分区,从而通过键进行事件排序!

以上是关于主题、分区和键的主要内容,如果未能解决你的问题,请参考以下文章

Kafka 如何在代理之间分配主题分区

分区 w.r.t 到代理和分区之间关于主题的关联

Kafka 分区机制详解

Kafka 主题分区到 Spark 流

2、kafka如何选定分区数量

Kafka - 主题 & 分区 & 消费者