我正在使用DirectRunner运行apache Beam KafkaIO的多个实例,它们是从同一主题中读取的。但是消息正在传递到所有正在运行的实例。看到我发现的Kafka配置后,组名将附加一些唯一的前缀,并且每个实例都有唯一的组名。
因此,每个实例都有唯一的 group.id 分配,这就是为什么将消息传递到所有实例的原因。
pipeline.apply("ReadFromKafka", KafkaIO.<String, String>read().withReadCommitted()
.withConsumerConfigUpdates(
new ImmutableMap.Builder<String, Object>().put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, true)
.put(ConsumerConfig.GROUP_ID_CONFIG, "my_group")
.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, 5).build())
.withKeyDeserializer(StringDeserializer.class).withValueDeserializer(StringDeserializer.class)
.withBootstrapServers(servers).withTopics(Collections.singletonList(topicName)).withoutMetadata()
那我必须给什么配置,以使组中的所有使用者都不会阅读相同的消息
答案 0 :(得分:0)
是的,这是因为组名被附加了一些唯一的前缀,并且每个实例都有唯一的组名。因此,kafka不知道您是否再启动一个实例。因此,相同的消息将传递给所有消费者。
因此,我能想到的一种解决方法是代替给出主题并让Beam确定所有分区的使用者数量,您可以使用DirectRunner为Apache Beam KafkaIO的每个实例显式给出主题分区。
您将必须将List
类型的TopicPartition
传递给方法withTopicPartitions
。
KafkaIO.<String, String>read()
.withCreateTime(Duration.standardMinutes(1))
.withReadCommitted()
.withBootstrapServers(endPoint)
.withConsumerConfigUpdates(new ImmutableMap.Builder<String, Object>()
.put(ConsumerConfig.GROUP_ID_CONFIG, groupName)
.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, 5)
.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "latest")
.build())
.withTopicPartitions(Arrays.asList(new TopicPartition(topicName, 0)))
.withKeyDeserializer(StringDeserializer.class)
.withValueDeserializer(StringDeserializer.class)
.withoutMetadata();
上面的代码将仅从partition 0
中读取消息。因此,通过这种方式,您可以旋转同一程序的多个实例,而不会将相同的消息传递给所有使用者