【问题标题】:Kafka consumer groups and partitionsKafka 消费者组和分区
【发布时间】:2017-05-03 15:31:14
【问题描述】:

我很难把握分区和客户群背后的关系。

这些想法本身就很清楚,推送到主题的每条消息都会复制到它的所有分区,对吧? 这样,如果两个不同的客户端连接到同一主题的两个不同分区,那么它们应该消费并提交相同的消息,而不会相互中断。

据我所知,消费者组是对分区概念的抽象,它们本质上承诺相同的事情,连接到同一主题的两个不同消费者组的两个不同客户端应该消费并提交相同的消息而不会相互中断.

因此,正如我所看到的,应该遵循连接到同一消费者组的两个客户端将使用来自同一分区的消息,而连接到两个不同消费者组的两个客户端将使用来自两个不同分区的消息(假设有该主题至少有两个分区),否则消费者组的想法不符合分区的想法。

但是,当我在 C# 中运行一个简单的消费者客户端时

string group = Console.ReadLine();

            var config = new Dictionary<string, object>()
            {
                { "group.id", group },
                { "bootstrap.servers", "10.0.0.3:9092" },
                { "enable.auto.commit", true },
                { "auto.commit.interval.ms", 1000 }
            };

            using (var consumer = new Consumer<Null, string>(config, null, new StringDeserializer(Encoding.UTF8)))
            {
                consumer.Subscribe(new List<string>() { { "myFirstTopic" } });
                while (true)
                {
                    Message<Null, string> msg;
                    if (!consumer.Consume(out msg, TimeSpan.FromMilliseconds(100)))
                    {
                        continue;
                    }

                    Console.WriteLine($"Topic: {msg.Topic} Partition: {msg.Partition} Offset: {msg.Offset} {msg.Value}");
                }
            }

我得到这个结果:

同一个消费者组从 2 个不同的分区消费。 当我运行来自不同消费者组(a 和 b)的两个客户端时,我得到了这个:

两个不同的消费者群体从相似的分区消费。

我不明白这是怎么回事,是不是说消费者群体的想法和分区的想法是矛盾的?

如果同一个消息在同一个分区下的两个不同的消费者组中出现,是不是意味着同一个消息被插入了两次到同一个分区?

请帮助我理解。

【问题讨论】:

    标签: c# apache-kafka


    【解决方案1】:

    你对消费者群体的理解是正确的,但是partition中的细节需要澄清一下。

    这些想法本身就很清楚,每条推送到主题的消息都会复制到它的所有分区,对吧?

    不完全是。一条消息将被写入单个分区(及其副本)。写入主题的所有消息都将在主题的分区之间拆分。因此,每个分区将只包含写入主题的所有消息的子集。

    请注意,副本只是确保 Kafka 集群中数据可用性的一种方式,以防 Kafka 节点出现故障。不影响消息处理语义。

    所以在我看来,应该遵循连接到同一消费者组的两个客户端将使用来自同一分区的消息...

    Kafka 一次只允许一个客户端从一个分区消费。因此,同一个消费者组中的任何一个客户端都不会消费来自同一个分区的数据。但是,它们一次可以消耗多个分区。此外,如果您的客户端多于单个组中的分区,则某些客户端将根本无法获取任何数据,因为没有分区可供它们使用数据。

    由于分区只有一个数据子集,并且一次只分配给一个客户端,因此每个客户端将使用写入主题的唯一数据子集。因此,您可以说具有单个消费者组排列的多分区的工作方式类似于工人模式。

    Kafka 中的分区驱动消息处理的并行化因素。您的主题拥有的分区越多,您可以拥有的并行工作的客户端就越多。

    ...连接到两个不同消费者组的两个客户端将从两个不同的分区消费(假设该主题至少有两个分区),因为否则消费者组的想法不符合分区。

    如果您的客户端在不同的消费者组中,他们可以从相同的分区消费。因此,所有的消费者组都会收到相同的数据集。多个消费组排列类似于扇出模式。

    Kafka 保证消息的顺序,对吗?它如何与同一主题的多个分区一起使用?事实上,我亲眼看到它并不总是正确的,它仅适用于单个分区吗?

    您的观察是正确的。只能保证每个分区的消息顺序。幸运的是,具有相同 key 的消息最终会在同一个分区中,因此您可以保证按 key 排序。

    例如,假设您有一个针对所有论坛帖子 cmets 的主题。如果您只关心单个论坛帖子中 cmets 的排序,则可以选择论坛帖子标识符作为所有 cmets 的消息键。

    我读到当我提交一个偏移量时,它是作为分区的一部分而不是消费者组提交的,所以如果我在一个组中提交一个偏移量,如果它从同一个分区中提取,它会影响另一个组的偏移量?

    偏移量存储在每个分区和消费者组中,即消费者组可以有自己的分区偏移量。这样偏移量就不会在组之间重叠。

    【讨论】:

    • 我希望这个答案能更清楚地说明发生了什么。如有必要,我很乐意添加更多详细信息。
    • 感谢您的详细回答,我想我更了解组和分区之间的关系。我还有一些不清楚的地方。 1. Kafka保证消息的顺序,对吧?它如何与同一主题的多个分区一起使用?事实上,我亲眼看到它并不总是正确的,它只适用于单个分区吗? 2. 我读到当我提交一个偏移量时,它是作为分区的一部分而不是消费者组提交的,所以如果我在一个组中提交一个偏移量,如果它从同一个分区中提取,它会影响另一个组的偏移量吗?
    • @Arik 我根据您的评论在我的回答中添加了更多细节。
    • @JaakkoPallari 惊人的答案!一个关于排序的问题留在我的脑海中:如果节点接收到分区 A 的消息 1、分区 B 的消息 2 和分区 A 的消息 3。分区 A 是否有可能以某种方式将消息 3 放置在其队列中在消息 1 之前?
    • @payne 谢谢,很高兴你发现它有用!据我了解,消息 3 不能放在 1 之前,除非节点先收到消息 3。如果您最终在分区中看到 3 before 1,我怀疑消息生产者可能会乱序写入它们。
    猜你喜欢
    • 1970-01-01
    • 2017-01-04
    • 2014-10-25
    • 2016-04-13
    • 2018-02-05
    • 2017-10-17
    • 2018-10-03
    • 2020-05-09
    • 1970-01-01
    相关资源
    最近更新 更多