代码之家  ›  专栏  ›  技术社区  ›  PatPanda

3个应用程序集并发性(1)与1个应用程序集中并发性(3)之间的差异

  •  -1
  • PatPanda  · 技术社区  · 3 年前

    我有一个关于Kafka与Spring Kafka并发性的问题。我有一个卡夫卡主题 theimportanttopic 许多消息都是通过它发送的。事实上,这个Kafka主题有三个分区。(称他们为重要主题-0重要主题-1重要主题-2)

    众所周知,Kafka不允许来自同一组的多个消费者使用来自同一分区的消息。即,同一组中没有两个消费者可以从重要主题-0消费。

    我的Spring Kafka应用程序代码如下:

    @Configuration
    class KafkaConsumerConfig {
    
        @Bean
        public Map<String, Object> consumerConfigs() {
            Map<String, Object> props = new HashMap<>();
            props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "mykafka.com:9092");
            props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
            return props;
        }
    
        @Bean
        public ConsumerFactory<String, String> consumerFactory() {
            return new DefaultKafkaConsumerFactory<>(consumerConfigs());
        }
    
        @Bean
        public KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<String, String>> kafkaListenerContainerFactory() {
            ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
            factory.setConsumerFactory(consumerFactory());
            factory.setConcurrency(1); //HERE
            return factory;
        }
    }
    
    @Component
    class KafkaListenersExample {
    
        Logger LOG = LoggerFactory.getLogger(KafkaListenersExample.class);
    
        @KafkaListener(topics = "theimportanttopic", groupId = "uniquegroup")
        void listener(String data) {
            LOG.info(data);
            doSomethingImportantWithTheData(data);
        }
    }
    

    因此,我很难理解这两种结构之间的区别:

    假设这个应用程序已经被固定化,并且云环境已经可以使用了。

    设计编号1:这个应用程序,因为它像Kubernetes一样位于部署在云上的容器中,所以它会生成三个实例。 根据定义,我将有三个这样的“应用程序”,每个应用程序将从三个分区中的一个分区消耗。

    kubectl get pods
    my-app-AaAaAaAaAa-AaAaA
    my-app-BbBbBbBbBb-BbBbB
    my-app-CcCcCcCcCc-CcCcC
    

    (假设我的应用AaAaAaAaA消耗重要主题-0,我的应用BbBbBb Bb BbB重要主题-1,my-app-CcCCCCCCCCCcCcCc重要主题-2)

    设计编号2: 另一方面,我可以有一个,而且只有一个这个应用程序我的应用程序在容器中,将并发设置为3。(与上述代码相同,仅更改一行)

    @Bean
    public KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<String, String>> kafkaListenerContainerFactory() {
        ConcurrentKafkaListenerContainerFactory<String, String> factory =
                new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(consumerFactory());
        factory.setConcurrency(3);
        return factory;
    }
    

    请问这两种设计有什么不同?

    哪一个是首选,为什么请?

    这不是一个基于观点的问题。1号设计和2号设计的性能、成本、优缺点是什么?

    0 回复  |  直到 3 年前
        1
  •  1
  •   OneCricketeer Gabriele Mariotti    3 年前

    不同之处在于高可用性。

    如果你有任何一个pod,消耗了所有三个分区,并且它停止了,那么你需要在k8s中进行额外的配置,以获得RestartPolicy。

    或者,使用一个maxContainers为3的ReplicaSet,然后Kafka Consumer API可以在其中任何一个启动/停止时重新平衡。

    您还可以查看KEDA以根据消费者滞后自动缩放。

    推荐文章