主题、分区和键
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 guarantees
和 load 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
选择分区。
如果key
和partition
都不存在,则将在round-robin fashion
中分配一个分区。
【讨论】:
发送分区消息的规则很好。? 感谢您解释键和分区号之间的区别。在尝试使用 kafka-console-producer 工具时,这让我大吃一惊。消息没有出现在我认为我指定的分区中,结果证明是键值。 两个键可以有相同的分区吗?不同key的消息如何存储在同一个partition中? 因此,如果我们指定一个与我们的对象相对应的键(例如客户编号),我们会得到一致的对象分配给分区,从而通过键进行事件排序!以上是关于主题、分区和键的主要内容,如果未能解决你的问题,请参考以下文章