我有一个关于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号设计的性能、成本、优缺点是什么?