简体   繁体   English

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

[英]Spring Kafka with multiple Partition & multiple listener

I want to setup multiple partition for a topic, Let say 3 partition.我想为一个主题设置多个分区,比如说 3 个分区。 Also it would have 3 consumers within same group reading from these partition (1-1 mapping as per kafka design).此外,同一组中将有 3 个消费者从这些分区中读取数据(根据 kafka 设计的 1-1 映射)。

My configurations are as follows:我的配置如下:

@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);
}

When i run this from single instance of my service then listeners are running fine with reading message from their respective topic-partition (no duplicate).当我从我的服务的单个实例运行它时,监听器运行良好,可以从各自的主题分区(无重复)读取消息。 But when i created 2 instance of the service then listener from both the instances are reading from same topic-partition again.但是,当我创建了 2 个服务实例时,这两个实例的侦听器都再次从同一个主题分区中读取。 This leads to duplicate processing of same message.这会导致对同一消息的重复处理。

My question is if i didn't change group id of listener in both instances then why listeners in different instance reading same message again.我的问题是,如果我在两种情况下都没有更改侦听器的组 ID,那么为什么不同实例中的侦听器会再次读取相同的消息。 Also how can i ensure it works fine as in single instance.另外,我如何确保它在单个实例中正常工作。 Thanks谢谢

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

You are manually assigning the partitions so the group.id is irrelevant for assignment purposes.您正在手动分配分区,因此group.id与分配目的无关。

If you want to distribute the partitions across multiple instances using group management, you need to just use ContainerProperties containerProps = new ContainerProperties(topic);如果要使用组管理将分区分布在多个实例中,则只需使用ContainerProperties containerProps = new ContainerProperties(topic); . .

You will need at least 6 partitions for 2 instances with concurrency = 3;对于 2 个并发 = 3 的实例,您将需要至少 6 个分区; otherwise you will have idle consumers.否则你会有空闲的消费者。

When there is only one instance, it will get all 6 partitions.当只有一个实例时,它将获得所有 6 个分区。

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

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