我正在阅读基于data
字段分区的Kafka主题equipmentId
。总共有15个分区,每个设备一个。
主题中的数据如下所示:
{
"timeStamp": "2018-05-03T14:32:04.910Z",
"series": "production-output",
"equipmentId": "5454-07",
"value": 1
}
在equipmentId
下的同一分区中,可能存在两个记录之一,production-output
或production-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。
谢谢!
答案 0 :(得分:1)
我相信,除非您可以保证所有分区的时间戳的前进进展,因为您要在源外提取时间戳和水印,否则会出现此错误。
您可以做的是将您的SeriesMap
课程用作Kafka DeserializationSchema,然后对您的Kafka来源执行assignTimestampsAndWatermarks
。然后,Kafka在每个分区内的时间戳分别向前移动都没有问题,它发出的全局水印将是所有分区中遇到的水印的最小值。
换句话说,执行此操作时,您的全局事件时间将以最慢分区的速度向前移动。这里的重要警告是,每个分区必须至少发出一些数据,否则您的前进时间将停止。
请注意,Flink中的时间是全局的而不是每个键。