Kafka工作队列具有动态数量的并行使用者

时间:2018-07-17 02:00:09

标签: parallel-processing apache-kafka kubernetes queue

我想用Kafka来“划分工作”。我想将某个工作实例发布到某个主题,并运行一组由相同使用者组成的云进行处理。每个消费者完成工作后,都会从该主题中选择下一个工作。每件作品只能由一位消费者处理一次。处理工作非常昂贵,因此我将需要许多在许多计算机上运行的消费者来跟上进度。我希望消费者的数量根据需要增加和减少(我打算为此使用Kubernetes)。

我发现了一种模式,其中为每个使用者创建了唯一的分区。这“划分了工作”,但是在创建主题时设置了分区数。此外,必须在命令行上创建主题,例如

bin/kafka-topics.sh --zookeeper localhost:2181 --partitions 3 --topic divide-topic --create --replication-factor 1

...

for n in range(0,3):
    consumer = KafkaConsumer(
                     bootstrap_servers=['localhost:9092'])
    partition = TopicPartition('divide-topic',n)
    consumer.assign([partition])
    ...

我可以为每个消费者创建一个唯一的主题,并编写自己的代码以将工作分配给这些主题。这似乎很麻烦,我仍然必须通过命令行创建主题。

具有动态数量的并行使用者的工作队列是一种常见的体系结构。我不能成为第一个需要这个的人。用Kafka正确的方法是什么?

3 个答案:

答案 0 :(得分:2)

您找到的图案是准确的。请注意,一旦创建了主题(有一些陷阱),也可以使用Kafka Admin APIpartitions can also be added创建主题。

在Kafka中,划分工作并允许缩放的方法是使用partitions。这是因为在使用者组中,每个分区都可以随时由一个使用者使用。

例如,您可以拥有一个包含50个分区的主题,并且有一个消费群体订阅了该主题:

  • 当吞吐量低时,组中只能有几个使用方,他们应该能够处理流量。

  • 当吞吐量增加时,您可以添加使用者(最多分区数)(在此示例中为50)来承担一些工作。

在这种情况下,扩展规模限制为50个使用者。消费者可以暴露许多指标(例如滞后),使您可以随时决定是否有足够的指标

答案 1 :(得分:0)

谢谢Mickael向我指出正确的方向。

https://www.safaribooksonline.com/library/view/kafka-the-definitive/9781491936153/ch04.html

Kafka consumers are typically part of a consumer group. When multiple
consumers are subscribed to a topic and belong to the same consumer group,
each consumer in the group will receive messages from a different subset of
the partitions in the topic.

https://dzone.com/articles/dont-use-apache-kafka-consumer-groups-the-wrong-wa

Having consumers as part of the same consumer group means providing the
“competing consumers” pattern with whom the messages from topic partitions
are spread across the members of the group. Each consumer receives messages 
from one or more partitions (“automatically” assigned to it) and the same
messages won’t be received by the other consumers (assigned to different 
partitions). In this way, we can scale the number of the consumers up to the
number of the partitions (having one consumer reading only one partition); in
this case, a new consumer joining the group will be in an idle state without 
being assigned to any partition.

用于在3个使用者之间划分工作的示例代码,最多100个:

bin/kafka-topics.sh --partitions 100 --topic divide-topic --create --replication-factor 1 --zookeeper localhost:2181

...

for n in range(0,3):
    consumer = KafkaConsumer(group_id='some-constant-group',
                     bootstrap_servers=['localhost:9092'])
    ...

答案 2 :(得分:0)

我认为您在正确的道路上-

这里涉及一些步骤-

  1. 创建Kafka主题并创建所需的分区。分区数是并行度的单位。换句话说,您需要运行许多消费者来处理工作。
  2. 如果缩放要求增加,则可以增加分区。但是它带有诸如重新分区之类的警告。请阅读有关新增分区的kafka文档。
  3. 为消费者定义一个Kafka消费者组。 Kafka会将分区分配给使用者组中的可用使用者,并自动重新平衡。如果添加/删除了使用者,kafka会自动进行重新平衡。
  4. 如果将使用者打包为docker容器,则使用kubernetes有助于管理容器,尤其是在多节点环境中。其他工具包括docker-swarm,openshift,Mesos等。
  5. Kafka提供分区顺序。
  6. 签出交付保证-至少一次,根据您的用例恰好一次。

或者,您可以使用Kafka Streams APIS。 Kafka Streams是一个客户端库,用于处理和分析存储在Kafka中的数据。它建立在重要的流处理概念上,例如正确区分事件时间和处理时间,窗口支持以及简单而有效的管理和实时查询应用程序状态。

相关问题