如何从kafka流中获取窗口聚合?

时间:2018-06-18 07:28:18

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

我有一系列事件,我想根据时间窗口聚合。我的解决方案提供增量聚合,而不是在定时窗口上提供聚合。我已经读过这对于流是正常的,因为它会将结果作为change-log。在研究过程中,我遇到了2 step windowed aggregation with Kafka Streams DSLHow to send final kafka-streams aggregation result of a time windowed KTable?。但是第一篇文章中的解决方案有点过时(使用已弃用的API)。我使用了那些弃用的API中建议的新API。这是我的解决方案,

KStream<String, Event> eventKStream = summarizableData.mapValues(v -> v.getEvent());
    KGroupedStream<String, Event> kGroupedStream = eventKStream.groupBy((key, value) -> {
             String groupBy = getGroupBy(value, criteria);
             return groupBy;
    }, Serialized.with(Serdes.String(), eventSerde));


    long windowSizeMs = TimeUnit.SECONDS.toMillis(applicationProperties.getWindowSizeInSeconds());
    final TimeWindowedKStream<String, Event> groupedByKeyForWindow = kGroupedStream
            .windowedBy(TimeWindows.of(windowSizeMs)
                    .advanceBy(windowSizeMs));

但是我的结果,正如我之前解释的那样,没有在具体的时间窗口中给出,而是作为增量聚合给出。我需要将我的数据输出为windowSize中给出的指定时间。另外我读到CACHE_MAX_BYTES_BUFFERING_CONFIG可以控制输出,但我需要一些可靠的解决方案适用于每个场景。另请注意,https://cwiki.apache.org/confluence/display/KAFKA/Windowed+aggregations+over+successively+increasing+timed+windows wiki中给出的模式现在已过时,因为它使用的是旧API。 (我使用kafka-streams 1.1.0版本)

1 个答案:

答案 0 :(得分:1)

问题是我的错误。上面的代码示例工作正常。但最后我将KTable转换为KStream。那就是问题所在。转换为KStream会导致输出中间结果aslo。 https://cwiki.apache.org/confluence/display/KAFKA/Windowed+aggregations+over+successively+increasing+timed+windows中给出的模式运行正常。有问题的代码是,

// Aggregation

KTable<Windowed<String>, Event> results = groupedByKeyForWindow.aggregate(new AggregateInitiator(), new EventAggregator());

// This converstion causing changelog to output. Instead use next line.
KStream<String, AggregationMessage> aggregationMessageKStream = results.toStream((key, value) -> key.toString())
                .mapValues(this::convertToAggregationMessage).filter((k, v) -> v != null);

// output KTable to sample topic. But this output controlled by 
// COMMIT_INTERVAL_MS_CONFIG and CACHE_MAX_BYTES_BUFFERING_CONFIG parameters. 
// I'm using default values for these params.
results.to(windowedSerde, eventSerde,  "Sample");