我有以下情况
stream<Tuple2<String, Integer>
.keyBy(0)
.timeWindow(Time.of(10, TimeUnit.SECONDS))
.sum(1)
.flatMap(..)
.sink()
我要做的是为我的时间窗口计算前N个。 每个窗口的前N都由接收器存储。
我可以计算flatmap中的前N个,但我不知道何时将其发送到接收器进行存储。据我所知,没有办法知道窗口在flatmap函数中何时结束。
我知道有一些替代方法,例如apply函数可以同时执行或在流中创建标记以指示结束,但我想知道是否有更优雅的解决方案。
答案 0 :(得分:1)
如果要计算所有键上每个窗口的顶部N
,那么您应该应用一个时间窗口,所有时间窗口的长度都与您计算顶部N
的应用方法的长度相同。你可以这样做:
final int n = 10;
stream
.keyBy(0)
.timeWindow(Time.of(10L, TimeUnit.SECONDS))
.sum(1)
.timeWindowAll(Time.of(10L, TimeUnit.SECONDS))
.apply(new AllWindowFunction<Tuple2<String,Integer>, Tuple2<String, Integer>, TimeWindow>() {
@Override
public void apply(TimeWindow window, Iterable<Tuple2<String, Integer>> values, Collector<Tuple2<String, Integer>> out) throws Exception {
PriorityQueue<Tuple2<String, Integer>> priorityQueue = new PriorityQueue<>(n, new Comparator<Tuple2<String, Integer>>() {
@Override
public int compare(Tuple2<String, Integer> o1, Tuple2<String, Integer> o2) {
return o1.f1 - o2.f1;
}
});
for (Tuple2<String, Integer> value : values) {
priorityQueue.offer(value);
while (priorityQueue.size() > n) {
priorityQueue.poll();
}
}
for (Tuple2<String, Integer> stringIntegerTuple2 : priorityQueue) {
out.collect(stringIntegerTuple2);
}
}
})
.print();