Spring @StreamListener进程(KStream <!-?,?-> stream)分区

时间:2019-02-15 20:50:49

标签: apache-kafka-streams spring-cloud-stream

我的流处理器中有一个带有多个分区的主题,我只是想从一个分区中进行流式处理,因此无法弄清楚如何配置它

spring.cloud.stream.kafka.streams.bindings.input.consumer.application-id=s-processor
spring.cloud.stream.bindings.input.destination=uinput
spring.cloud.stream.bindings.input.group=r-processor
spring.cloud.stream.bindings.input.contentType=application/java-serialized-object
spring.cloud.stream.bindings.input.consumer.header-mode=raw
spring.cloud.stream.bindings.input.consumer.use-native-decoding=true

spring.cloud.stream.bindings.input.consumer.partitioned=true

@StreamListener(target = "input")
// @SendTo(value = { "uoutput" })
public void process(KStream<UUID, AModel> ustream) {

我只希望该处理器处理一个分区数据,其他分区将有其他处理器

到目前为止,我的发现与https://kafka.apache.org/20/javadoc/org/apache/kafka/streams/StreamsConfig.html#PARTITION_GROUPER_CLASS_CONFIG有关,但找不到如何在spring application.properties中设置此属性。

2 个答案:

答案 0 :(得分:1)

我认为分区分组程序是在单个处理器中将分区与任务分组。如果要确保处理器仅处理单个分区,则需要至少提供与主题分区相同数量的处理器实例。例如如果您的主题有4个分区,那么您需要有4个流应用程序实例,以确保每个实例仅处理一个分区。

答案 1 :(得分:0)

Kafka Streams不允许读取单个分区。如果订阅主题,则所有分区都将被使用并分布在可用实例上。因此,您无法事先知道将哪个分区分配给了哪个实例,并且所有实例都执行相同的代码。

  

但是链接到处理器的每个分区具有不同种类的数据,因此需要不同的处理器应用程序

在这种情况下,处理器(或变压器)必须能够处理所有分区的数据。 Kafka Streams通过ProcessorContext对象公开分区号,该对象通过init()方法传递给处理器:https://kafka.apache.org/20/javadoc/org/apache/kafka/streams/kstream/Transformer.html#init-org.apache.kafka.streams.processor.ProcessorContext-

因此,您需要在转换器内进行“分支”以基于分区应用不同的处理逻辑:

ustream.transform(() -> new MyTransformer());


class MyTransformer implement Transformer {
  // other methods omitted

  R transform(K key, V value) {
    switch(context.partition()) { // get context from `init()`
      case 0:
        // your processing logic
        break;
      case 1:
        // your processing logic
        break;

      // ...
  }
}