【问题标题】:Understanding Kafka Topics and Partitions了解 Kafka 主题和分区
【发布时间】:2016-10-27 17:30:29
【问题描述】:

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

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

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

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

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

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

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

【问题讨论】:

    标签: apache-kafka kafka-consumer-api kafka-producer-api


    【解决方案1】:

    这篇文章已经有了答案,但我正在用来自 Kafka Definitive Guide 的几张图片添加我的观点

    在回答问题之前,让我们看一下生产者组件的概述:

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

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

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

    2。当订阅者正在运行时 - 它是否指定了其组 ID,以便它可以成为同一主题的消费者集群的一部分,或者该消费者组感兴趣的多个主题的一部分?

    您应该始终配置 group.id,除非您使用的是简单分配 API,并且您不需要在 Kafka 中存储偏移量。它不会是任何组的一部分。 source

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

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

    • 消费者数量小于主题分区数,则可以将多个分区分配给组中的一个消费者
    • 消费者数量与主题分区数量相同,那么分区和消费者映射可以如下所示,
    • 消费者数量高于主题分区数量,则分区和消费者映射如下图,无效,检查消费者5

    4。作为broker创建的partition,消费者不用担心?

    消费者应了解分区的数量,如问题 3 中所述。

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

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

    更多关于小组协调员

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

    6。从队列中删除消息时会发生什么? - 比如retention是3小时,然后时间过去了,offset双方是怎么处理的?

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

    【讨论】:

    • 嗨!我是公认答案的作者,但我认为你的答案也非常好,尤其是在第 3 点,图表让事情变得更加清晰 200%!你认为我们应该合并吗?
    • 我的意思是我(或您)可以将您的答案元素合并到我的答案中,以提高他们的知名度并改进此(当前)最佳答案。但没有你的同意,我不会这样做!
    • 为什么不能将多个消费者映射到一个分区?确保消息只处理一次?谢谢你的回答。
    • @g10guang:是因为commit offset维护困难。
    • 另一种情况。您可以有一个分区和多个消费者订阅/分配给它。代理只会将记录交付给第一个注册的消费者。但是让我们假设第一个消费者比轮询间隔花费更多的时间来处理任务。记录消费不提交给代理。经纪人了解消费者闲逛。在这种状态下,代理触发重新平衡,将新分配的分区发送给它的所有消费者。该消息被另一个消费者再次消费,即使它仍在由 C1 处理。小心。
    【解决方案2】:

    让我们按顺序来吧:)

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

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


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

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


    3 - 每个消费者组在代理上是否有一个对应的分区,还是每个消费者都有一个?

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


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

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


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

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


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

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

    【讨论】:

    • 对不起 :) 在 500 个字符框中解释整个 kafka 过程有点困难,我建议阅读kafka.apache.org/documentation.html#theconsumer(可能还有第 4 节的其余部分,关于 kafka 内部结构)。基本上:消费者 request 保存偏移量,但那些保存在其他地方。
    • 我刚读了这个,但仍然没有解释它的存放位置:Kafka 以不同的方式处理这个问题。我们的主题被划分为一组完全有序的分区,每个分区在任何给定时间由一个消费者消费。这意味着消费者在每个分区中的位置只是一个整数,即下一条要消费的消息的偏移量。这使得关于已消费的状态非常小,每个分区只有一个数字。这种状态可以定期检查点。这使得消息确认的等价物非常便宜。
    【解决方案3】:

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

    为了平衡负载,可以将一个主题划分为多个分区并跨代理复制。

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

    分区中的消息具有唯一标识分区内每条消息的顺序 id 号。

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

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

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

    在这篇文章中有很好的解释:http://codeflex.co/what-is-apache-kafka/

    【讨论】:

    • Partition 只是为了主题负载均衡吗?
    • @g10guang:分区也有助于并行处理消息。
    • 如果我错了,请纠正我,当生产者发送消息并进入主题时,它会根据配置将其复制到分区,然后消费者消费它。对吗?
    • @Atul 消息将根据当前的 Partitioner 配置附加到该主题的 1 个分区(默认情况下,消息键的哈希决定消息去往哪个分区),是的,消费者将在使用该分区中的消息时获取消息
    • @Kevin Hooke,感谢您的解释并澄清我的理解。
    【解决方案4】:
    1. 当生产者生成消息时,它会指定要将消息发送到的主题,对吗?它关心分区吗?

    是的,生产者确实指定了主题

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

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


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

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


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

    每个消费者组分配一个分区,多个消费者组可以访问一个分区,但不能将属于一个消费者组的两个消费者分配到同一个分区,因为消费者在一个组中顺序消费消息,如果一个组中有多个消费者从同一个分区消费消息,那么序列可能会丢失,而逻辑上独立的组可以从同一个分区消费。


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

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

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

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


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

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


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

    它会根据需要自动重新配置自己。它应该给出一个错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-01
      • 2016-11-15
      • 2015-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多