Apache Kafka消息广播

时间:2018-08-06 07:48:48

标签: java apache-kafka

我正在学习Apache-kafka,有些困惑。请帮助我了解以下情况。

我有一个在Kafka集群中有5个分区和5个代理的主题。我正在分区1(例如P1)中维护消息顺序。我想向10个消费者广播P1消息。

所以我的问题是;这10个使用者如何与主题分区p1交互。

3 个答案:

答案 0 :(得分:1)

这可能不是您想要使用Kafka的方式。

除非您对设置键的方式很明确,否则您无法真正控制生成主题时消息最终到达哪个分区。 Kafka中的分区被设计为更像是低级管道,这种管道已经存在,但是您通常不必与之交互。在使用者方面,将根据任一时刻某个特定使用者组的活动使用者数量为您分配分区。

解决此问题的一种方法是将一个主题定义为仅具有一个分区,在这种情况下,当然,所有消息都将进入该分区。这并不理想,因为Kafka无法并行化数据摄取或服务,但有可能。

因此,话虽如此,让我们假设您确实设法将所有消息放入特定主题的分区1中。当您用消费者组ID为consumer1激发该主题的消费者时,将为该主题分配 all 分区,因为该消费者是该特定组的唯一活动对象ID。如果只有一个分区用于该主题(如上文所述),那么该使用者将获得所有数据。然后,如果您启动具有相同组ID的第二个使用者,Kafka将注意到该特定组ID的第二个使用者,但是由于只有一个分区,它无法为其分配任何分区,因此,该使用者将永远无法获得任何数据。

另一方面,如果您用另一个消费者组ID触发第三个消费者,请说consumer2 消费者现在将获取所有数据,而不会由于Kafka会分别跟踪其消耗偏移量,因此根本不会干扰consumer1消息的消耗。 Kafka会跟踪每个分区上每个特定ConsumerGroupId的偏移量,因此,如果其中一个开始缓慢消耗或停止一段时间并在当天晚些时候重新开始消耗,则不会感到困惑。

此处提供有关Kafka工作原理的更多详细信息:https://kafka.apache.org/documentation/#gettingStarted

有关如何使用Kafka使用者的更多信息,请访问此链接: https://kafka.apache.org/20/javadoc/index.html?org/apache/kafka/clients/consumer/KafkaConsumer.html

答案 1 :(得分:0)

@mjuarez的回答是绝对正确的-为了简洁起见,我将其简化为以下内容;

请勿尝试仅从单个分区读取数据,因为它是低级构造,并且在某种程度上破坏了Kafka的并行性。如果您需要更好的数据分离,最好只创建更多的主题。

我还要补充一点,大多数情况下,消费者不需要知道消息来自哪个分区,就像我不会根据三明治来自哪个商店一样吃三明治。

答案 2 :(得分:0)

@mjuarez实际上是不正确的,我不确定OP为何会错误地确认他的评论。您可以使用以下命令绝对明确地告诉Kafka生产者记录属于哪个分区:

ProducerRecord(
        java.lang.String topic,
        java.lang.Integer partition, // <--------- !!!
        java.lang.Long timestamp,
        K key,
        V value)

https://kafka.apache.org/10/javadoc/org/apache/kafka/clients/producer/ProducerRecord.html#ProducerRecord-java.lang.String-java.lang.Integer-java.lang.Long-K-V-

所以在那之后大部分的话都变得无关紧要了。

现在直接解决OP问题:您想完成广播。要发送一次消息并多次阅读,则每个阅读者都必须有一个不同的消费者组。

该用例是绝对有效的Kafka使用范例。

您也可以使用RabbitMQ完成此操作: https://www.rabbitmq.com/tutorials/tutorial-three-java.html ...但是这样做的方式并不理想,因为其中涉及多个进程外队列。