使用Flink使用DateStreamSource <list <t >>分配水印的正确方法

时间:2018-11-22 06:32:19

标签: apache-flink flink-streaming

我有一个连续的JSONArray数据生成给Kafka主题,并且我想处理具有EventTime特性的记录。为了实现此目标,我必须为JSONArray中包含的每个记录分配水印。

我没有找到实现此目标的便捷方法。我的解决方案是使用DataStreamSource>中的数据,然后使用匿名ProcessFunction迭代List并将对象收集到下游,最后向该下游分配水印。

主要代码如下:

DataStreamSource<List<MockData>> listDataStreamSource = KafkaSource.genStream(env); SingleOutputStreamOperator<MockData> convertToPojo = listDataStreamSource .process(new ProcessFunction<List<MockData>, MockData>() { @Override public void processElement(List<MockData> value, Context ctx, Collector<MockData> out) throws Exception { value.forEach(mockData -> out.collect(mockData)); } }); convertToPojo.assignTimestampsAndWatermarks( new BoundedOutOfOrdernessTimestampExtractor<MockData>(Time.seconds(5)) { @Override public long extractTimestamp(MockData element) { return element.getTimestamp(); } }); SingleOutputStreamOperator<Tuple2<String, Long>> countStream = convertToPojo .keyBy("country").window( SlidingEventTimeWindows.of(Time.seconds(10), Time.seconds(10))) .process( new FlinkEventTimeCountFunction()).name("count elements");

毫无疑问,代码似乎还可以,也可以正常运行。但是ProcessWindowFunction从未触发。我跟踪了Flink源代码,发现EventTimeTrigger从未返回TriggerResult.FIRE,由TriggerContext.getCurrentWatermark导致始终返回Long.MIN_VALUE。

在事件发生时处理List的正确方法是什么?任何建议将不胜感激。

1 个答案:

答案 0 :(得分:0)

问题是您将keyBy和window操作应用到convertToPojo流,而不是带有时间戳和水印(未分配给变量)的流。

如果您大致像这样编写代码,那么它应该可以工作:

listDataStreamSource = KafkaSource ...
convertToPojo = listDataStreamSource.process ...
pojoPlusWatermarks = convertToPojo.assignTimestampsAndWatermarks ...
countStream = pojoPlusWatermarks.keyBy ...

在convertToPojo流上调用assignTimestampsAndWatermarks不会修改该流,而是创建一个包含时间戳和水印的新数据流对象。您需要将窗口应用于该新数据流。