基于事件时间的Flink时间窗口什么也不输出

时间:2018-07-18 10:43:10

标签: apache-flink

在流处理问题中,我们有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, {})

2 个答案:

答案 0 :(得分:2)

是否一切都迟了?

默认情况下,每200毫秒调用一次定期水印生成器(实时测量,而不是事件时间)。根据您的情况,这可能会很长。使用setAutoWatermarkInterval进行更改。您可能还需要考虑使用setBufferTimeout来减少延迟。

答案 1 :(得分:0)

我认为您的问题是您需要在时间戳记上输入密码。

您应该具有keyBy(0),以便按传感器ID分割流。