来自Kafka流的EventTime窗口导致“Timestamp monotony violated”错误

时间:2018-05-03 15:44:36

标签: apache-flink

我正在阅读基于data字段分区的Kafka主题equipmentId。总共有15个分区,每个设备一个。

主题中的数据如下所示: { "timeStamp": "2018-05-03T14:32:04.910Z", "series": "production-output", "equipmentId": "5454-07", "value": 1 } equipmentId下的同一分区中,可能存在两个记录之一,production-outputproduction-input。 我的目标是根据eventTime将每分钟的产量总和相加。

这是我的代码到目前为止的样子

    env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
    env.setParallelism(15);

        // Add kafka consumer to DataStream
    DataStream<String> stream = env.addSource(kafkaConsumer);

    DataStream keyedStream = stream
            .map(new SeriesMap())
            // Filter "production-output" seriesType
            .filter(new FilterFunction<Tuple4<Long, String, String, Double>>() {
                @Override
                public boolean filter(Tuple4<Long, String, String, Double> data) throws Exception {
                    if (data.f1.equals("production-output")) {
                        return true;
                    }
                    return false;
                }
            })
            // Key on "equipmentId"
            .keyBy(2);

    DataStreamSink sink = keyedStream
            .assignTimestampsAndWatermarks(new AscendingTimestampExtractor<Tuple4<Long, String, String, Double>>() {
                @Override
                public long extractAscendingTimestamp(Tuple4<Long, String, String, Double> data) {
                    return data.f0;
                }
            })
            // Key on "equipmentId"
            .keyBy(2)
            .timeWindow(Time.seconds(1))
            .sum(3)
            .print();

所以我认为问题来自keyedStream没有为每个密钥创建单独的流。

如果我要执行此操作:

        DataStreamSink sink = keyedStream.print();

输出如下:

15> (1525358087756,production-output,5454-07,1.0)
2> (1525358080269,production-output,5454-05,1.0)
2> (1525358085361,production-output,5454-05,1.0)
2> (1525358088469,production-output,5454-05,1.0)
2> (1525358097630,production-output,5454-05,1.0)
13> (1525358222081,production-output,5454-06,1.0)
13> (1525358223162,production-output,5454-06,1.0)
...
13> (1525358230305,production-output,5454-06,1.0)
13> (1525358234453,production-output,5454-06,1.0)
15> (1525358231998,production-output,5454-01,1.0)
15> (1525358231783,production-output,5454-10,1.0)
15> (1525358232803,production-output,5454-01,1.0)
15> (1525358233811,production-output,5454-01,1.0)
...
15> (1525358238878,production-output,5454-10,1.0)

因此,流15正在为设备5454-10,01和07获取数据 而输出中不存在流4,5,6,7,8,10,11,12和14。

并非每台机器都有数据,所以我认为我可以面对this issue

但是,我认为正在发生的事情是为一个线程found in this question分配了多个密钥

非常感谢任何帮助!

注意:我可以保证每个分区的时间戳顺序是顺序的。

更新:我按照Joshua DeWald的建议做了,并在来源上致电assignTimestampsAndWatermarks。我不再看到Timestamp monotony violated的原始问题,但现在遇到FLINK-5479

谢谢!

1 个答案:

答案 0 :(得分:1)

我相信,除非您可以保证所有分区的时间戳的前进进展,因为您要在源外提取时间戳和水印,否则会出现此错误。

您可以做的是将您的SeriesMap课程用作Kafka DeserializationSchema,然后对您的Kafka来源执行assignTimestampsAndWatermarks。然后,Kafka在每个分区内的时间戳分别向前移动都没有问题,它发出的全局水印将是所有分区中遇到的水印的最小值。

换句话说,执行此操作时,您的全局事件时间将以最慢分区的速度向前移动。这里的重要警告是,每个分区必须至少发出一些数据,否则您的前进时间将停止。

请注意,Flink中的时间是全局的而不是每个键。