防止KStream发出旧的未更改的合计值

时间:2019-05-23 20:10:55

标签: apache-kafka aggregation apache-kafka-streams

我有一个KStream管道,该管道按键分组,然后按一定的时间间隔对窗口进行分组,然后在该管道上应用自定义聚合:

KStream<String, Integer> input = /* define input stream */

/* group by key and then apply windowing */
KTable<Windowed<String>, MyAggregate> aggregateTable = 
    input.groupByKey()
         .windowedBy(/* window defintion here */)
         .aggregate(MyAggregate::new, (key, value, agg) -> agg.addAndReturn(value))

// I need to get a change log of aggregateTable so:
aggregateTable.toStream().to("output-topic");

问题在于大多数输入记录不会更改MyAggregate对象的内部状态。结构类似于:

class MyAggregate {

    private Set<Integer> checkBeforeInsert = /* some predefined values */
    private List<Integer> actualState = new ArrayList<>();

    public MyAggregate addAndReturn(Integer value) {

        /* for 99% of records the if check passes */
        if (checkBeforeInsert.contains(value)) {
            /* do nothing and return. Note that the state hasn't been changed */
            return this;
        } else {
            actualState.add(value);
            return this;
        }
    }
}

但是,KStream没有任何线索表明聚合对象尚未更改,它仍然存储聚合(与旧的相同)。它还将传播到相同的旧值以更改日志主题,并使用相同的旧值触发aggregateTable.toStream()

尽管我的应用程序的语义正常(其他应用程序意识到未更改状态可能会到达这一事实),但这会在中间主题上产生巨大的噪音。我需要一种方法来通知KStream汇总是否确实已更改并且应该存储或与先前的记录相同(只是忽略它)。

0 个答案:

没有答案