繁体   English   中英

Spring 具有多个分区和多个侦听器的 Kafka

[英]Spring Kafka with multiple Partition & multiple listener

我想为一个主题设置多个分区,比如说 3 个分区。 此外,同一组中将有 3 个消费者从这些分区中读取数据(根据 kafka 设计的 1-1 映射)。

我的配置如下:

@Bean
public ConcurrentMessageListenerContainer<String, String> kafkaMessageContainer() throws Exception {
    
    //Setting 3 Partition
    ContainerProperties containerProps = new ContainerProperties(new TopicPartitionOffset(topic, 0), new TopicPartitionOffset(topic, 1), new TopicPartitionOffset(topic, 2));
    //Group id is set same for multiple instances of this service
    containerProps.setGroupId(groupId);
    
    ConcurrentMessageListenerContainer<String, String> factory = new ConcurrentMessageListenerContainer <String, String>(kafkaConsumerFactory(kafkaBootStrapServers), containerProps);
    
    factory.setErrorHandler(new SeekToCurrentErrorHandler(new FixedBackOff(KAFKA_RETRY_INTERVAL, KAFKA_RETRY_MAX_ATTEMPT)));
    //Setting 3 listeners
    factory.setConcurrency(3);
    
    return factory;
}
private ConsumerFactory<String, String> kafkaConsumerFactory(String kafkaBootStrapServers) {
        
    Map<String, Object> config = new HashMap<String, Object>();
    config.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaBootStrapServers);
    config.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
    config.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
    config.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "true");
    
    return new DefaultKafkaConsumerFactory<String, String>(config);
}

当我从我的服务的单个实例运行它时,监听器运行良好,可以从各自的主题分区(无重复)读取消息。 但是,当我创建了 2 个服务实例时,这两个实例的侦听器都再次从同一个主题分区中读取。 这会导致对同一消息的重复处理。

我的问题是,如果我在两种情况下都没有更改侦听器的组 ID,那么为什么不同实例中的侦听器会再次读取相同的消息。 另外,我如何确保它在单个实例中正常工作。 谢谢

ContainerProperties containerProps = new ContainerProperties(new TopicPartitionOffset(topic, 0), new TopicPartitionOffset(topic, 1), new TopicPartitionOffset(topic, 2));

您正在手动分配分区,因此group.id与分配目的无关。

如果要使用组管理将分区分布在多个实例中,则只需使用ContainerProperties containerProps = new ContainerProperties(topic); .

对于 2 个并发 = 3 的实例,您将需要至少 6 个分区; 否则你会有空闲的消费者。

当只有一个实例时,它将获得所有 6 个分区。

暂无
暂无

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

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