Flink 中的时间概念

StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime); 
// alternatively:
// env.setStreamTimeCharacteristic(TimeCharacteristic.IngestionTime);
// env.setStreamTimeCharacteristic(TimeCharacteristic.ProcessingTime);

Watermark 水位

考虑这样一个问题,在基于 EventTime 处理的时候,Flink 是如何知道何时应该触发统计计算的呢?Watermark 就是为此而生的。

有界乱序下的 Watermark

有界乱序下的 Watermark

而相反,在有界无需的数据流中,通过 Watermark 就可以有效处理,如上图所示

  1. 首先 Flink 不可能无限等待一个数据,所以这里有一个最大容忍值 maxOutOfOrderness , 表示可以容忍几个时间单位,如上图我们设置 maxOutOfOrderness 为 4,也就是说,如果接收到一个 EventTime 时间为 7 的数据,此处 Watermark 值应为 7-4 = 3。即当前 Watermark 在 3 处。
  2. 每当有新的最大时间戳出现时( 大于当前最大的 EventTime ),就可以产生新的Watermark。如上图出现了 11 之后,Watermark 将为被更新为 7,而此时再出现 9 的延时数据,则不会触发 Watermark 更新。
  3. 当新出现的数据 EventTime 小于当前的 Watermark 时,认为该数据是一个 Late Event,在 Window 计算的时候将不会纳入到计算范围当中。如上图的 19,因为此时 Watermark 为 20,所以会被丢弃。

Flink 运行流程中的 Watermark

在 Flink 的运行过程中,Watermark 将伴随整个数据的处理过程,如下图所示

  1. Watermark 也是一种特殊事件,当 Watermark 被更新时,就是产生一个包含当前 Watermark 的特殊事件,并发送给下游 operator
  2. 每个 operator 也包含有一个自己的时间,只有当接收到 Watermark 事件之后,才会取其时间更新自己的 operator 时间,并再次发送给下游。就是说 Watermark 事件将会伴随着数据一致传递给下游。

另一种特殊的 Watermark

除了基于 EventTime 的 Watermark,Watermark 还有一种生成策略 Punctuated Watermark。是基于事件流中的一种特殊事件作为 Watermark。