Kafka Streams窗口聚合批处理

时间:2018-09-24 16:24:51

标签: java apache-kafka apache-kafka-streams

我的应用程序中有Kafka Streams处理:

myStream
    .mapValues(customTransformer::transform)
    .groupByKey(Serialized.with(new Serdes.StringSerde(), new SomeCustomSerde()))
    .windowedBy(TimeWindows.of(10000L).advanceBy(10000L))
    .aggregate(CustomCollectorObject::new,
            (key, value, aggregate) -> aggregate.collect(value),
            Materialized.<String, CustomCollectorObject, WindowStore<Bytes, byte[]>>as("some_store_name")
                    .withValueSerde(new CustomCollectorSerde()))
    .toStream()
    .foreach((k, v) -> /* do something very important */);

预期的行为::传入消息按关键字分组,并在一定时间间隔内在CustomCollectorObject中汇总。 CustomCollectorObject只是其中包含List的类。在foreach中每隔10秒之后,我就对汇总数据进行了非常重要的操作。重要的是,我希望每10秒调用一次foreach

实际行为::我可以看到foreach中的处理被称为是稀有的,大约每30-35秒,这没什么大不了的。重要的是,我一次收到3-4条消息。

问题是:我如何达到预期的行为?我需要我的数据在运行时得到处理,而没有任何延迟。

我尝试设置cache.max.bytes.buffering: 0,但是在这种情况下,窗口根本不起作用。

1 个答案:

答案 0 :(得分:0)

Kafka Streams具有不同的执行模型,并且提供了不同的语义,即,您的期望与Kafka Streams的不匹配。已经有多个类似的问题:

还要注意,社区当前正在使用一个名为suppress()的新运算符,该运算符将能够提供所需的语义:https://cwiki.apache.org/confluence/display/KAFKA/KIP-328%3A+Ability+to+suppress+updates+for+KTables

现在,您需要在状态存储中添加一个transform(),并使用标点符号来获取所需的语义(参见https://docs.confluent.io/current/streams/developer-guide/processor-api.html#defining-a-stream-processor