当前位置: 首页 > 知识库问答 >
问题:

当并发=分区计数时,spring集成kafka侦听器线程读取多个分区

甄煜
2023-03-14

我设置了一个Spring集成流程来处理一个有3个分区的主题,并将侦听器容器的并发性设置为3。正如所料,我看到三个线程处理来自所有3个分区的批处理。然而,我发现在某些情况下,一个侦听器线程可能处理包含来自多个分区的消息的单个批处理。在kafka中,我的数据是按id划分的,因此它可以与其他id同时处理,但不能在另一个线程上与相同的id一起处理(我很惊讶地发现这种情况正在发生)。通过阅读文档,我认为每个线程都将被分配一个分区。我正在使用这样的KafkaMessageDrivenChannelAdapter:

private static final Class<List<MyEvent>> payloadClass = (Class<List<MyEvent>>)(Class) List.class;

public KafkaMessageDrivenChannelAdapterSpec.KafkaMessageDrivenChannelAdapterListenerContainerSpec<String, MyEvent> myChannelAdapterSpec() {
        return Kafka.messageDrivenChannelAdapter(tstatEventConsumerFactory(),
                KafkaMessageDrivenChannelAdapter.ListenerMode.batch, "my-topic") //3 partitions
                .configureListenerContainer(c -> {
                    c.ackMode(ContainerProperties.AckMode.BATCH);
                    c.id(_ID);
                    c.concurrency(3);
                    RecoveringBatchErrorHandler errorHandler = new RecoveringBatchErrorHandler(
                            (record, exception) -> log.error("failed to handle record at offset {}: {}",
                                    record.offset(), record.value(), exception),
                            new FixedBackOff(FixedBackOff.DEFAULT_INTERVAL, 2)
                    );
                    c.errorHandler(errorHandler);
                });
    }
@Bean
public IntegrationFlow myIntegrationFlow() {
        return IntegrationFlows.from(myChannelAdapterSpec())
                .handle(payloadClass, (payload, headers) -> {
                    service.performSink(payload);
                    return null;
                })
                .get();
    }

如何设置它,使每个侦听器容器线程只处理来自一个分区的消息?

共有1个答案

林俊晖
2023-03-14

但是,是否还有一种方法可以防止从多个分区获取带有消息的批处理,即使确实发生了重新平衡?

消费者团体不是这么运作的。如果你想拥有一个“粘性”消费者,那么考虑使用手动分配。请参见基于< code>TopicPartitionOffset的通道适配器工厂...主题分区:

/**
 * Create an initial
 * {@link KafkaMessageDrivenChannelAdapterSpec.KafkaMessageDrivenChannelAdapterListenerContainerSpec}.
 * @param consumerFactory the {@link ConsumerFactory}.
 * @param listenerMode the {@link KafkaMessageDrivenChannelAdapter.ListenerMode}.
 * @param topicPartitions the {@link TopicPartitionOffset} vararg.
 * @param <K> the Kafka message key type.
 * @param <V> the Kafka message value type.
 * @return the KafkaMessageDrivenChannelAdapterSpec.KafkaMessageDrivenChannelAdapterListenerContainerSpec.
 */
public static <K, V>
KafkaMessageDrivenChannelAdapterSpec.KafkaMessageDrivenChannelAdapterListenerContainerSpec<K, V> messageDrivenChannelAdapter(
        ConsumerFactory<K, V> consumerFactory,
        KafkaMessageDrivenChannelAdapter.ListenerMode listenerMode,
        TopicPartitionOffset... topicPartitions) {

然后,它不会被视为使用者组,您必须创建多个通道适配器,每个适配器都指向其特定分区。所有这些通道适配器都可以向同一消息通道发出消息

 类似资料:
  • 在Master Hazelcast电子书“17.4.1.分区感知操作”下,它指出: 要执行分区感知操作,需要创建操作线程数组。 单个操作线程对多个分区执行操作; 每个分区只属于1个操作线程。 忽略备份和近缓存,当我创建一个IMap实例时,这是否意味着我只能有一个并发的put/get操作在整个集群的每个map分区上执行?进一步说,如果我附加了一个MapStore,这是否意味着我只能对我的后端数据库运

  • 我已经使用Spring Kafka创建了一个Kafka消费者,并将其部署在云铸造中。该主题有10个分区。我计划将应用程序扩展到10个实例,以便每个实例可以使用来自一个分区的消息。Spring Kafka支持并发消息侦听器容器,我猜它支持从每个分区创建多个线程来使用。例如,如果我有5个消费者实例,每个消费者实例可能有2个线程从分区消耗。因为我计划为每个分区创建一个应用实例,所以使用并发消费者有什么好

  • uuusing Spring Kafka org . Spring framework . Kafka . listener . concurrentmessagelistenercontainer根据ContainerProperties和主题中的分区数量创建多个侦听器。javadoc说“来自同一个分区的消息将被顺序处理”。因此,如果只有1个分区,并发性设置为10,会发生什么——不会有任何并发性

  • 数据流很简单 Kafka- “一些逻辑”是这里的瓶颈,所以我想使用更多的线程/任务来提高吞吐量,而不是增加kafka分区(目前为3个)。输入和输出主题之间的顺序在这里并不重要。 使用Apache Storm可以轻松完成。我可以为一些逻辑增加螺栓的并行度。如何使用Flink做到这一点?更普遍的问题是,是否有任何简单的方法可以在Flink的不同阶段使用不同的并行度?

  • 我需要实现下面的数据流。我有一个kafka主题,它有9个分区。我可以用9个并行级别阅读这个主题。我还有3个节点Flink集群。这个集群的每个节点都有24个任务槽。 首先,我想传播我的kafka,每个服务器有3个分区,如下所示。顺序没关系,我只转换kafka消息并发送DB。 第二件事是,我想在保存NoSQL DB的同时提高并行度。如果我增加并行度48,因为发送DB是IO操作,它不会消耗CPU,我想确

  • 如果我是正确的,默认情况下,spark streaming 1.6.1使用单线程从每个Kafka分区读取数据,假设我的Kafka主题分区是50,这意味着每50个分区中的消息将按顺序读取,或者可能以循环方式读取。 案例1: -如果是,那么我如何在分区级别并行化读取操作?创建多个< code > kafkautils . createdirectstream 是唯一的解决方案吗? 案例2: -如果我的