测试Flink窗口

时间:2020-02-26 16:12:10

标签: testing apache-flink flink-streaming

我有一个简单的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测试应用程序的简单方法吗?

谢谢!

1 个答案:

答案 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;
    }
}

有关事件时间,水印和窗口的更多信息,请参见documentationtutorials

相关问题