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

TJ-*_*TJ- 7 apache-kafka kafka-consumer-api

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

是循环赛吗?是从第一个开始读取下一个之前的所有内容吗?我用来consumer.poll(N)投票。

Thr*_*idh 5

订购相当复杂。以下是 Kafka 2.6 的工作原理:

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

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

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

因此,您将进行一种批量循环。