Apache Flink:从不执行Windowed ReduceFunction

时间:2017-06-29 06:39:25

标签: java apache-flink flink-streaming

下面的

是代码片段,我正在使用基于Tumbling EventTime的窗口

DataStream<OHLC> ohlcStream = stockStream.assignTimestampsAndWatermarks(new TimestampExtractor()).map(new mapStockToOhlc()).keyBy((KeySelector<OHLC, Long>) o -> o.getMinuteKey())
        .timeWindow(Time.seconds(60))
        .reduce(new myAggFunction());

不幸的是,它似乎永远不会影响reduce函数。如果使用上面没有窗口的代码,reduce函数可以正常工作。下面是TimestampExtractor的代码。 30秒水印延迟仅用作测试值,但是一分钟的翻滚窗口是m

    public static class TimestampExtractor implements AssignerWithPeriodicWatermarks<StockTrade> {
    @Nullable
    @Override
    public Watermark getCurrentWatermark() {
        return new Watermark(System.currentTimeMillis() - 30000);
    }

    @Override
    public long extractTimestamp(StockTrade stockTrade, long l) {
        BigDecimal bd = new BigDecimal(stockTrade.getTime());
        // bd contains miliseconds timestamp 1498658629.036
        return bd.longValue();
    }
}

bd.longValue()返回秒时间戳1498658629,因为我的窗口也以秒为单位定义。
当我使用返回分钟时间戳的bd.longValue()/ 60时,调用reduce函数。我的输出文件包含每个reduce操作的所有记录

{time=1498717692.000, minuteTime=24978628, n=1, open=2248.0}
{time=1498717692.000, minuteTime=24978628, n=2, open=2248.0}
...
{time=1498717692.000, minuteTime=24978628, n=8, open=2248.0}

那么,任何人都可以向我解释一下,发生了什么?很多。

1 个答案:

答案 0 :(得分:3)

通常水印应该与数据中的时间戳相关,而不应该基于系统时钟。使用事件时间的一个好处是,可以使用相同的应用程序重新处理历史数据或处理当前数据,但如果您将时间戳与系统时钟进行比较,那么这是不可能的,因为您和# 39;已经完成了。

水印可以被认为是一个声明,表明时间戳小于水印的所有数据都已到达。换句话说,任何时间戳小于当前水印的数据都将被视为迟到。我的猜测是你没有看到任何结果,因为你的水印导致你的所有数据被延迟考虑,窗口操作员正在丢弃所有这些后期数据。

我建议您改用BoundedOutOfOrdernessTimestampExtractor。它的工作原理是跟踪到目前为止在数据流中看到的最大时间戳,并从该最大时间戳而不是系统时钟中减去延迟。 source code,以防您感到好奇。