我有一个简单的Flink应用程序,该应用程序汇总了最后一分钟内具有相同ID和时间戳的事件:
DataStream<String> input = env
.addSource(consumerProps)
.uid("app");
DataStream<Pixel> pixels = input.map(record -> mapper.readValue(record, Pixel.class));
pixels
.keyBy("id", "timestampRoundedToMinutes")
.timeWindow(Time.minutes(1))
.sum("constant")
.addSink(dynamoDBSink);
env.execute(jobName);
我正在尝试使用documentation中推荐的方法来测试该应用程序。我也查看了this stackoverflow question,但添加接收器并没有帮助。
我确实有我的测试课中推荐的@ClassRule。该函数如下所示:
StreamExecutionEnvironment env=StreamExecutionEnvironment.getExecutionEnvironment();
env.setParallelism(2);
CollectSink.values.clear();
Pixel testPixel1 = Pixel.builder().id(1).timestampRoundedToMinutes("202002261219").constant(1).build();
Pixel testPixel2 = Pixel.builder().id(2).timestampRoundedToMinutes("202002261220").constant(1).build();
Pixel testPixel3 = Pixel.builder().id(1).timestampRoundedToMinutes("202002261219").constant(1).build();
Pixel testPixel4 = Pixel.builder().id(3).timestampRoundedToMinutes("202002261220").constant(1).build();
env.fromElements(testPixel1, testPixel2, testPixel3, testPixel4)
.keyBy("id","timestampRoundedToMinutes")
.timeWindow(Time.minutes(1))
.sum("constant")
.addSink(new CollectSink());
JobExecutionResult result = env.execute("AggregationTest");
assertNotEquals(0, CollectSink.values.size());
CollectSink是从documentation复制的。
我在做什么错?还有使用嵌入式kafka测试应用程序的简单方法吗?
谢谢!
答案 0 :(得分:3)
测试失败的原因是因为从未触发窗口。在窗口可以达到其分配的时间结束之前,作业将运行完成。
其原因与您处理时间的方式有关。通过指定
.keyBy("id","timestampRoundedToMinutes")
您正在将所有具有相同ID并在同一分钟内带有时间戳的事件安排在同一窗口中。但是,因为您使用的是处理时间窗口(而不是事件时间窗口),所以直到一天中运行测试的时间从一分钟跨到下一分钟时,窗口才会关闭。仅需处理四个事件,您的工作就不太可能运行足够长的时间来实现。
您应该做的更像是这样:将时间特征设置为事件时间,并提供时间戳提取器和水印分配器。请注意,通过此操作,无需将时间戳四舍五入为分钟边界,这是事件时间窗口无论如何要做的一部分。
public static void main(String[] args) throws Exception {
...
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
env.fromElements(testPixel1, testPixel2, testPixel3, testPixel4)
.assignTimestampsAndWatermarks(new TimestampsAndWatermarks())
.keyBy("id")
.timeWindow(Time.minutes(1))
.sum("constant")
.addSink(new CollectSink());
env.execute();
}
private static class TimestampsAndWatermarks extends BoundedOutOfOrdernessTimestampExtractor<Event> {
public TimestampsAndWatermarks() {
super(/* delay to handle out-of-orderness */);
}
@Override
public long extractTimestamp(Event event) {
return event.timestamp;
}
}
有关事件时间,水印和窗口的更多信息,请参见documentation和tutorials。