Java Kafka流窗口聚合不工作
我正在实现SpringJava应用程序,该应用程序需要使用事件(表示事务),按用户ID(这是关键)对它们进行分组,对它们进行计数并求和,然后将它们保存到数据库中。由于预计会有大量的事务,所以我尝试使用Kafka streams的窗口机制来聚合一些关闭的事务(关闭意味着接近时间),并将这些聚合对象保存到数据库中。这样可以减少对数据库的调用 以下是示例代码:Java Kafka流窗口聚合不工作,java,spring,apache-kafka,apache-kafka-streams,spring-kafka,Java,Spring,Apache Kafka,Apache Kafka Streams,Spring Kafka,我正在实现SpringJava应用程序,该应用程序需要使用事件(表示事务),按用户ID(这是关键)对它们进行分组,对它们进行计数并求和,然后将它们保存到数据库中。由于预计会有大量的事务,所以我尝试使用Kafka streams的窗口机制来聚合一些关闭的事务(关闭意味着接近时间),并将这些聚合对象保存到数据库中。这样可以减少对数据库的调用 以下是示例代码: public class Event { long userId; double amount; ... }
public class Event {
long userId;
double amount;
...
}
public class Aggregation {
long userId;
int count;
double amount;
...
}
public Function<KStream<String, Event>,
KStream<String, Aggregation>> process() {
return input -> input
.groupByKey()
.windowedBy(TimeWindows.of(Duration.ofSeconds(2)).grace(Duration.ZERO))
.aggregate(
Aggregation::new,
this::aggregation,
Materialized.with(Serdes.String(), aggregationSerde)
)
.suppress(Suppressed.untilWindowCloses(unbounded()))
.toStream()
.map((key, value) -> new KeyValue<>(key.key(), value));
}
public Aggregation aggregation(String key, Event event, Aggregation aggregation) {
log.info("Aggregating event for key={} event={} aggregation={}",
key, event, aggregation);
aggregation.incrementCount();
aggregation.addAmount(event.getAmount());
return aggregation;
}
公共类事件{
长用户标识;
双倍金额;
...
}
公共类聚合{
长用户标识;
整数计数;
双倍金额;
...
}
公共职能流程(){
返回输入->输入
.groupByKey()
.windowedBy(TimeWindows.of(持续时间秒(2)).grace(持续时间零))
.合计(
聚合::新,
这是聚合,
具体化的.with(Serdes.String(),aggregationSerde)
)
.suppress(supprested.untilwindowclose(unbounded()))
.toStream()
.map((key,value)->新的KeyValue(key.key(),value));
}
公共聚合(字符串键、事件、聚合){
log.info(“聚合键的事件={}事件={}聚合={}”,
键、事件、聚合);
aggregation.incrementCount();
aggregation.addAmount(event.getAmount());
收益聚合;
}
据我所知,聚合应该像常规Stream.reduce()方法一样工作,它提供了初始值,然后是一个表示如何将每个元素添加到结果的方法(“聚合”方法),该方法接收新事件(第一个和第二个参数)的键和值,以及迄今为止计算的结果(第三个参数)。但是,通过登录“aggregation”方法,在每次调用它时,我可以看到第3个参数实际上是一个新的聚合对象,就像没有任何对象被分组或放置在同一个窗口中一样(并且在2秒内有数据使用相同的键)
有一次,我怀疑按键分组不能正常工作(每个事件都属于它自己的组,因此聚合永远不会发生),但我还没有找到一种方法来检查这一点。有没有办法记录每个事件的组/窗口id之类的内容,并检查它们放在哪里
所以,以数据库结尾的数据实际上是正确的,但对数据库的插入/更新的数量并没有减少。有人知道我做错了什么吗
谢谢