时间语义和Watermark
时间语义
Flink中的时间语义
在Flink
的流式处理中,会涉及到时间的不同概念,如下图所示:
Event Time
:是事件创建的时间。它通常由事件中的时间戳描述,例如采集的 日志数据中,每一条日志都会记录自己的生成时间,Flink
通过时间戳分配器访问事 件时间戳。
Ingestion Time
:是数据进入 Flink
的时间。
Processing Time
:是每一个执行基于时间操作的算子的本地系统时间,与机器 相关,默认的时间属性就是Processing Time
例如,一条日志进入 Flink
的时间为 2017-11-12 10:00:00.123
,到达 Window
的 系统时间为 2017-11-12 10:00:01.234
,日志的内容如下:
2017-11-02 18:37:15.624 INFO Fail over to rm2
Event Time的引入
在 Flink
的流式处理中,绝大部分的业务都会使用 eventTime
,一般只在 eventTime
无法使用时,才会被迫使用 ProcessingTime
或者IngestionTime
。
如果要使用EventTime
,那么需要引入 EventTime
的时间属性,引入方式如下所示
val env = StreamExecutionEnvironment.getExecutionEnvironment
// 从调用时刻开始给 env 创建的每一个 stream 追加时间特征
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
我们可以看到TimeCharacteristic
是枚举时间类型
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package org.apache.flink.streaming.api;
import org.apache.flink.annotation.PublicEvolving;
@PublicEvolving
public enum TimeCharacteristic {
ProcessingTime,
IngestionTime,
EventTime;
private TimeCharacteristic() {
}
}
三个参数就是三个时间语义
事件时间语义不能简简单单的设置一下,需要设置一下那个字段作为时间语义
Waterkmark(水位线)
基本概念
我们知道,流处理从事件产生,到流经source
,再到 operator
,中间是有一个过 程和时间的,虽然大部分情况下,流到operator
的数据都是按照事件产生的时间顺 序来的,但是也不排除由于网络、分布式等原因,导致乱序的产生,所谓乱序,就 是指Flink
接收到的事件的先后顺序不是严格按照事件的Event Time
顺序排列的。
那么此时出现一个问题,一旦出现乱序,如果只根据 eventTime
决定 window
的运行,我们不能明确数据是否全部到位,但又不能无限期的等下去,此时必须要有 个机制来保证一个特定的时间后,必须触发 window
去进行计算了,这个特别的机 制,就是 Watermark
。
-
Watermark
是一种衡量Event Time
进展的机制。 -
Watermark
是用于处理乱序事件的,而正确的处理乱序事件,通常用Watermark
机制结合window
来实现。 -
数据流中的
Watermark
用于表示timestamp
小于Watermark
的数据,都已经 到达了,因此,window
的执行也是由Watermark
触发的。 -
Watermark
可以理解成一个延迟触发机制,我们可以设置Watermark
的延时时长t
,每次系统会校验已经到达的数据中最大的maxEventTime
,然后认定eventTime
小于maxEventTime - t
的所有数据都已经到达,如果有窗口的停止时间等于maxEventTime – t
,那么这个窗口被触发执行。 -
其实也就是说,
WaterMark
是一个时间的延迟,当时间事件到达之后,不立即计算,而是等待一段时间,上图的理想情况,以事件时间做系统时间,因为有有序的所以没问题,但是遇到无序事件时间时,如果大的时间时间先到,就会出现问题,因为时间是不可倒退的,所以需要设置一个时延,当5秒的数据输入时,此时认为系统时间为2秒
Watermark
的特点
Watermark
是一条特殊的数据记录Watermark
必须单调递增,以确保任务的事件时间再向前推进,而不是在后退Watermark
与数据的时间戳相关
理解案例
有序流的Watermark
如下图所示,Watermark
设置为0
我们可以看到,事件时间和系统时间是一致的
乱序流的Watermark
,Watermark
设置为2