繁体   English   中英

Kafka 消费者订阅多个主题时接收消息的顺序

[英]Order of receiving messages if Kafka consumer subscribes to multiple topics

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

是循环吗? 是从第一个读到下一个吗? 我使用consumer.poll(N)进行轮询。

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

当您调用consumer.poll(N) ,客户端确实将FetchRequest对象发送到托管分区领导者的代理(请参阅org.apache.kafka.clients.consumer.internals.Fetcher.createFetchRequests() ) - 每个节点只有一个请求,不是每个分区。

重要的是客户端可以为多个分区发送一个 FetchRequest(参见 协议规范)。

排序比较复杂。 以下是 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从队列中max.poll.records
  • 在记录返回给poll的调用者之前,另一个对所有节点的 fetch 请求被启动,但这一次,已经在扁平队列中的所有主题分区都被排除在外
  • 这适用于所有未来的poll

在实践中,这意味着您不会饿死,但您可能会收到来自一个主题的大量消息,然后才会收到下一个主题的大量消息。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM