本文说明一下flink的时间语义
处理时间(processTIme)
执行相关操作的机器系统时间。
如果flink的流式处理程序是基于processtime。那么代码中所有的操作都是将基于运算符的机器系统时钟时间。每小时的processTime window包括在系统时钟指示完整一个小时内的所有记录数据。例如,应用程序在上午8:20开始执行,那么第一个每小时的窗口上包括8:20-9:00之间处理的所有数据,下一个窗口将包括9:00-10:00之间的数据,以此类推。
事件时间 eventTime
事件时间是指原始事件发生在设备上的时间。这个是数据进入flink之前就携带的,并且可以从每个数据中提起该时间戳。eventTime程序中必须指定eventtime watermarks。
在一个完美的世界中,事件时间都是按照顺序发生的,数据进入到flink程序中也会按顺序,不会发生无序或者延时。但是实际情况不是这样的,由于各种原因,数据流在进入flink程序中总会发生延时和无序数据,但是在我们的每小时处理窗口中不可能一直等待下去。
Flink 中衡量事件时间进度的机制是watermarks。水印作为数据流的一部分流动并带有时间戳t。Watermark (t)声明事件时间已到达该流中的时间t,这意味着流中不应再有时间戳为 t’ <= t的元素(即时间戳早于或等于水印的事件)。
在上面的图片中可以看到流中的数据都是有序的。
在上面图二的流数据中是无序的。
在并行流中的watermark
在上图中,两个source流,的watermark分别是33,17; 在进过map的操作之后,map1的watermark为29,map2的watermark为17,在window1中操作,map1和map2的数据都会进入window1 的窗口,最终在窗口中会以最小的watermark来触发计算。在window2里面也是一样的操作。
迟到
基于现实世界的情况,数据流出现迟到的现象存在,那么在flink代码中允许设置迟到时间,这样在触发窗口的计算时需要加上延迟时间才可以触发窗口的计算。
使用事件时间窗口时,可能会发生元素迟到的情况,即Flink 用来跟踪事件时间进度的水印已经超过元素所属窗口的结束时间戳。有关 Flink 如何处理事件时间的更详尽的讨论,请参阅 事件时间,尤其是延迟元素。
默认情况下,当水印超过窗口末尾时,迟到的元素将被丢弃。但是,Flink 允许为窗口操作符指定最大允许延迟。Allowed lateness 指定元素在被丢弃之前可以延迟多少时间,其默认值为 0。在水印通过窗口末尾之后但在它通过窗口末尾之前到达的元素加上允许的迟到,仍然被添加到窗口中。根据使用的触发器,延迟但未丢弃的元素可能会导致窗口再次触发。的情况就是这样EventTimeTrigger。
DataStream<T> input = ...;
input
.keyBy(<key selector>)
.window(<window assigner>)
.allowedLateness(<time>)
.<windowed transformation>(<window function>);