簡體   English   中英

Spring Kafka:3 個應用程序 setConcurrency(1) 與 1 個應用程序 setConcurrency(3) 之間的區別

[英]Spring Kafka: Difference between 3 apps setConcurrency(1) vs 1 app setConcurrency(3)

關於卡夫卡與 Spring 卡夫卡並發的小問題請問。

我有一個 Kafka 主題theimportanttopic ,許多消息都通過它發送。 事實上,這個 Kafka 主題有三個分區。 (稱他們為theimportanttopic-0 theimportanttopic-1 theimportanttopic-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);
    }
}

有了這個,我很難理解這兩種結構之間的區別:

假設此應用程序已經 dockerized 並且雲環境已准備就緒。

我可以為構造 1 提供 1CPU + 1G 內存 *3,或者為構造 2 提供 3CPU +3G 內存。

設計編號 1:此應用程序,因為它位於部署在雲上的容器中,如 Kube.netes,所以啟動它的三個實例。 根據定義,我將擁有三個“應用程序”,並且每個應用程序都將使用三個分區中的一個。

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

(假設,my-app-AaAaAaAaAa-AaAaA 使用重要主題-0,my-app-BbBbBbBbBb-BbBbB 重要主題-1,my-app-CcCcCcCcCc-CcCcCtheimportanttopic-2)

設計編號 2:另一方面,我可以有一個,並且只有一個這個應用程序 my-app 在容器中,將並發設置為 3。(與上面相同的代碼,只需更改一行)

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

請問這兩種設計有什么區別?

哪一個是首選,為什么?

這不是一個基於意見的問題。 我可以知道設計編號 1 和設計編號 2 之間的性能、成本、優缺點是什么嗎?

謝謝

不同之處在於高可用性。

如果你有任何一個 pod,消耗了所有三個分區,並且它停止了,那么你需要在 k8s 中進行額外的配置以獲得 RestartPolicy。

或者,有一個 maxContainers 為 3 的 ReplicaSet,然后 Kafka Consumer API 可以在其中任何一個啟動/停止時重新平衡。

您還可以查看 KEDA,以根據消費者滯后自動縮放。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM