在流处理问题中,我们有3个传感器,每个传感器每8毫秒生成一个带时间戳的样本(传感器的时间是同步的)。所以我想为每个时间戳合并数据(如果有3个传感器,我们应该为每个时间戳输出3个合并的样本数据)。另外,我们有一个160毫秒的时间限制,因此每个数据自生成时间戳以来最多应在160毫秒后输出。因此,我决定使用Flink EventTime概念和一个时间窗口。由于时间戳在每个传感器的样本中都是唯一的,因此我们将其视为数据流的关键。
getBytes
在代码中,我们首先引入流的第二个字段作为事件时间,并设置一个周期性的水印(因为数据是以固定的速率生成的,具有固定的延迟)。之后,我们将事件时间设置为流的关键。我们也想收集最新数据,因此我们使用了env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
SingleOutputStreamOperator<Tuple3<String,Long, JSONObject>> res = aggregatedTuple
.assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor<Tuple3<String, Long, JSONObject>>(Time.milliseconds(160)) {
@Override
public long extractTimestamp(Tuple3<String, Long, JSONObject> element) {
return element.f1 ;
}
}).keyBy(1).timeWindow(Time.milliseconds(160))
.allowedLateness(Time.milliseconds(2))
.sideOutputLateData(lateOutputTag)
.reduce(Do merging samples);
。最后,我们使用相同的键来减少(合并)数据。问题是在Flink事件时间模式下,定义的窗口不输出任何数据!如果不设置事件时间,它将输出数据,但是我想将事件时间用作Flin窗口的时间。我尝试了多次窗口和水印,但它们没有输出任何东西。
我使用Flink计数窗口和自定义的超时触发器成功解决了相同的问题。
更新:传入的数据流格式为以下类型(如果我们有3个传感器):
sideOutputLateData
以此类推,每8毫秒一次。
在数据流中保存最新数据
sensor_id, timestamp, data
(1, 1531980773390, {})
(2, 1531980773390, {})
(3, 1531980773390, {})
(1, 1531980773398, {})
(2, 1531980773398, {})
(3, 1531980773398, {})
答案 0 :(得分:2)
是否一切都迟了?
默认情况下,每200毫秒调用一次定期水印生成器(实时测量,而不是事件时间)。根据您的情况,这可能会很长。使用setAutoWatermarkInterval进行更改。您可能还需要考虑使用setBufferTimeout来减少延迟。
答案 1 :(得分:0)
我认为您的问题是您需要在时间戳记上输入密码。
您应该具有keyBy(0),以便按传感器ID分割流。