如果Kafka使用者订阅了多个主题,则接收消息的顺序

时间:2018-11-05 05:50:29

标签: apache-kafka kafka-consumer-api

我有一个消费者调查多个主题。对于这个问题,我限制每个主题一个分区。假设当消费者开始轮询时,每个主题都有一些数据。 读取顺序是什么?

是循环吗?它是从头到尾读取的全部内容吗?我使用consumer.poll(N)进行轮询。

2 个答案:

答案 0 :(得分:1)

没有排序,因为底层协议允许在一个请求中发送针对多个分区的请求。

调用<MasterDetailPage.Master> <ContentPage Title="MasterP" > <StackLayout BackgroundColor="#01796F"> <StackLayout Margin="25,10,25,0" Padding="0,30,0,0"> <Image BackgroundColor="Accent" Aspect="AspectFill" Source="Enrich.png"></Image> </StackLayout> <StackLayout Margin="20,10,20,0" > <Button Margin="20,5,20,0" HorizontalOptions="FillAndExpand" Text="Menu 1"></Button> <Button Margin="20,0,20,0" HorizontalOptions="FillAndExpand" Text="Menu 1"></Button> <Button Margin="20,0,20,0" HorizontalOptions="FillAndExpand" Text="Menu 1"></Button> </StackLayout> </StackLayout> </ContentPage> </MasterDetailPage.Master> 时,客户端实际上将consumer.poll(N)对象发送给托管分区领导者的代理(请参见FetchRequest)-每个节点(而不是每个分区)只有一个请求。 / p>

重要的是,客户端可以为多个分区发送一个FetchRequest(请参见protocol spec)。

答案 1 :(得分:1)

排序非常复杂。这是适用于Kafka 2.6的工作方式:

  • 当您将主题分区分配给使用者时,这些主题分区将保留在哈希表中,因此顺序将是稳定的,但不一定是您使用的分区
  • 调用Consumer.poll(N)时,它将返回所有排队的消息,但最多返回max.poll.records(请参见下文)
  • 什么都没有排队时,您分配的所有主题分区都会按该主题分区负责人所在的Kafka节点进行分区
  • 这些列表中的每个列表均在获取请求中发送到各个节点
  • 每个节点最多返回fetch.max.bytes(或至少返回一条消息,如果可用)
  • 该节点将使用来自请求分区的消息填充这些字节,始终从第一个开始
  • 如果当前分区中没有更多消息,但仍有字节要填充,它将移动到下一个分区,直到没有更多消息或缓冲区已满
  • 即使当前分区中仍有消息可用,该节点也可以决定停止使用当前分区并继续下一个分区
  • 客户/消费者收到缓冲区后,它将把缓冲区拆分为CompletedFetches,其中一个CompletedFetch包含缓冲区中一个主题分区的所有消息
  • 那些CompletedFetches被排入队列(它们可能包含0条消息或1000或更多)。每个请求的主题分区将有一个CompletedFetch
  • 由于对节点的所有请求都是并行运行的,但是只有一个队列,因此CompletedFetches / topic分区可能会混合在最终结果中,而不是原始分配顺序
  • 排队的CompletedFetches在逻辑上被扁平化为一个大队列
  • Consumer.poll(N)将从该扁平队列中读取最多max.poll.records并使其出队
  • 在将记录返回给poll的调用者之前,将启动对所有节点的另一个获取请求,但是这次,将排除已经在扁平化队列中的所有主题分区
  • 这适用于以后所有的poll通话

实际上,这意味着您不会挨饿,但是在收到有关下一个主题的大量消息之前,您可能会从一个主题获得大量消息。

在消息大小为10字节的测试中,从一个主题读取大约58000条消息,然后从下一个主题读取大致相同的数量。 所有主题都预先填充了100万条消息。

因此,您将有一种批处理循环法。

相关问题