Performance 弹簧&x2B;卡夫卡:交易缓慢

Performance 弹簧&x2B;卡夫卡:交易缓慢,performance,apache-kafka,kafka-consumer-api,spring-kafka,Performance,Apache Kafka,Kafka Consumer Api,Spring Kafka,刚开始使用SpringKafka(2.1.4.RELEASE)和Kafka(1.0.0),但是当我添加事务时,处理速度降低了很多 代码: 在Java中,我添加了: @Bean ProducerFactory ProducerFactory(卡夫卡财产属性){ DefaultKafkaProducerFactory=新的DefaultKafkaProducerFactory(properties.buildProducerProperties()); setTransactionIdPrefix(

刚开始使用SpringKafka(2.1.4.RELEASE)和Kafka(1.0.0),但是当我添加事务时,处理速度降低了很多

代码:

在Java中,我添加了:

@Bean
ProducerFactory ProducerFactory(卡夫卡财产属性){
DefaultKafkaProducerFactory=新的DefaultKafkaProducerFactory(properties.buildProducerProperties());
setTransactionIdPrefix(properties.getProducer().getTransactionIdPrefix());
返回工厂;
}
@豆子
卡夫卡模板卡夫卡模板(生产工厂){
返回新的KafkaTemplate(factory,true);
}
@Bean(“kafkaListenerContainerFactory”)
ConcurrentKafkaListenerContainerFactory listenerContainerFactory(环境环境环境、消费者工厂、KafkaTransactionManager事务管理器){
ConcurrentKafkListenerContainerFactory=新ConcurrentKafkListenerContainerFactory();
工厂设置自动启动(真);
工厂设置并发(1);
setConsumerFactory(consumerFactory);
factory.getContainerProperties().setTransactionManager(transactionManager);
factory.getContainerProperties().setGroupId(env.getRequiredProperty(“spring.kafka.consumer.groupID”);
返回工厂;
}

当我删除
setTransactionManager(transactionManager)
语句时,速度大幅提高。有什么我做错了吗?

卡夫卡事务非常昂贵-尤其是如果您提交每个发送

向下滚动至“事务如何执行以及如何调整它们”

正如我们所看到的,开销与作为事务一部分写入的消息数量无关。因此,提高吞吐量的关键是每个事务包含更多的消息

使用Spring for Apache Kafka,您可以使用
executeInTransaction
方法在同一事务中执行多个发送。或者通过使用带有
KafkaTransactionManager
的Spring事务管理,并在
@Transactional
方法中执行多个发送

编辑

我没有注意到侦听器容器;我假定您正在使用一条消息,执行一些转换并发送到另一个主题。因此,在这种情况下,您不能“在一个事务中发送多条消息”,因为容器管理该事务,并且默认情况下,在每次传递之后提交

增加并发性不会影响事务语义;在您的情况下(并发性为10),分区分布在10个线程上。每个线程运行一个单独的事务

通过在容器工厂上将
batchListener
设置为
true
,可以进一步提高速度

在这种情况下,您的
@KafkaListener
将获得一个
列表(或者
列表
,如果您正在使用转换);您可以迭代列表,处理每条记录,并将其与模板一起发送(不要使用
executeInTransaction
,因为已经有一个由容器线程启动的事务)。然后,当批处理完成时,容器将提交事务


您可以使用kafka
max.poll.records
consuer属性控制批大小。

我明白了。我尝试将其更改为批处理模式,一次轮询100条记录,并发10条。这使它快了很多,但是事务将如何工作呢?到底是一次还是一次?如果在5条记录之后失败,事务在哪里包装?大约100读,10并发或?见编辑我的答案;我没有注意到您使用的是事务性消费者;在那种情况下,情况有点不同。
spring.kafka.consumer.max-poll-records=10
spring.kafka.consumer.specific.avro.reader=true
spring.kafka.consumer.auto-offset-reset=earliest
spring.kafka.consumer.group-id=${application.name}
spring.kafka.consumer.properties.isolation.level=read_committed
spring.kafka.consumer.key-deserializer=io.confluent.kafka.serializers.KafkaAvroDeserializer
spring.kafka.consumer.value-deserializer=io.confluent.kafka.serializers.KafkaAvroDeserializer