Flink基础介绍-3 Time与Window
- 三、流处理中的Time与Window
- 3.1 Time
- 3.2 window
- 3.3 Window API
- 3.4 Watermark
三、流处理中的Time与Window
3.1 Time
Event Time:是事件创建的时间。它通常由事件中的时间戳描述,例如采集的日志数据中,每一条日志都会记录自己的生成时间,Flink通过时间戳分配器访问事件时间戳。
Ingestion Time:是数据进入Flink的时间。
Processing Time:是每一个执行基于时间操作的算子的本地系统时间,与机器相关,默认的时间属性就是Processing Time。
3.2 window
在流式计算中,数据持续不断的流入计算引擎,需要一个窗口限定计算范围,窗口定义了该范围,辅助完成有界范围的数据处理。Flink支持多种窗口类型,按照驱动类型分为:时间驱动的Time Window(如每30秒钟)和数据驱动的Count Window(如每100个事件),按照窗口的滚动方式又可以分成:翻滚窗口(Tumbling Window,无重叠),滚动窗口(Sliding Window,有重叠)和会话窗口(Session Window,活动间隙)。
Flink的DataStream API将窗口抽象成独立的Operator,且支持很多窗口算子,每个窗口算子包含Window Assigner 、Windows Function、触发器、剔除器、时延设定等部分属性,其中Window Assigner 和 Windows Function是必须要指定的属性。
Window Assigner用来决定某个元素被分配到哪个/哪些窗口中去;Trigger触发器决定了一个窗口何时能够被计算或清除,每个窗口都会拥有一个自己的Trigger;Evictor驱逐者在Trigger触发之后,在窗口被处理之前,Evictor(如果有Evictor的话)会用来剔除窗口中不需要的元素,相当于一个filter。
(1)固定窗口(Fixed Windows):有时也称之为翻滚窗口(Tumbling WIndows),固定窗口按固定的时间段或长度(比如小时或元素个数)来分片数据集。固定窗口可应用到数据集中的所有数据上,因此它通常被称为对齐窗口。但有时为了把窗口计算的负荷均匀分摊到整个时间范围内,会把固定窗口的边界时间加上一个随机数,这样的固定窗口则变成了不对齐窗口。
(2)滑动窗口(Sliding Windows):它是固定窗口的一般化形式。由窗口大小以及滑动周期构成(比如以小时作为窗口大小,分钟作为滑动周期)。如果滑动周期小于窗口大小,那么窗口会发生部分重叠;而如果滑动周期跟窗口大小相等,则该窗口就是固定窗口。滑动窗口通常也是对齐的,出于性能考虑某些情况下也可以是非对齐的。需要注意的是,上图为了表明滑动的性质而没有把每个窗口对应到所有的键,实际情况是每个窗口都会对应到所有的键。
(3)会话窗口(Session Windows):它是一种动态窗口,用于在数据的子集上(比如某个键所对应的数据集)捕获一些活跃的阶段性的数据集。通常会话窗口会定义一个超时时间间隙(Gap),任何发生在小于超时时间点的持续时间段内的事件都归属于同一个会话。会话窗口是非对齐窗口。会话窗口常用于用户行为分析,即观察在一个会话窗口内用户的一系列操作所产生的事件。
3.3 Window API
(1)TimeWindow
TimeWindow是将指定时间范围内的所有数据组成一个window,一次对一个window里面的所有数据进行计算(就是本文开头说的对一个边界内的数据进行计算)。
(2)CountWindow
CountWindow根据窗口中相同key元素的数量来触发执行,执行时只计算元素数量达到窗口大小的key对应的结果。
注意:CountWindow的window_size指的是相同Key的元素的个数,不是输入的所有元素的总数。
(3)Window Reduce
WindowedStream → DataStream:给window赋一个reduce功能的函数,并返回一个聚合的结果。
(4)Window Apply
apply方法可以进行一些自定义处理,通过匿名内部类的方法来实现。当有一些复杂计算时使用。
(5)Window Fold
WindowedStream → DataStream:给窗口赋一个fold功能的函数,并返回一个fold后的结果。
(6)Aggregation on Window
WindowedStream → DataStream:对一个window内的所有元素做聚合操作。min和 minBy的区别是min返回的是最小值,而minBy返回的是包含最小值字段的元素(同样的原理适用于 max 和 maxBy)。
Window 总结
(1)flink支持两种划分窗口的方式(time和count)
如果根据时间划分窗口,那么它就是一个time-window
如果根据数据划分窗口,那么它就是一个count-window
(2)flink支持窗口的两个重要属性(size和interval)
如果size=interval,那么就会形成tumbling-window(无重叠数据)
如果size>interval,那么就会形成sliding-window(有重叠数据)
如果size<interval,那么这种窗口将会丢失数据。比如每5秒钟,统计过去3秒的通过路口汽车的数据,将会漏掉2秒钟的数据。
(3)通过组合可以得出四种基本窗口
time-tumbling-window:无重叠数据的时间窗口,设置方式举例:timeWindow(Time.seconds(5))
time-sliding-window:有重叠数据的时间窗口,设置方式举例:timeWindow(Time.seconds(5), Time.seconds(3))
count-tumbling-window:无重叠数据的数量窗口,设置方式举例:countWindow(5)
count-sliding-window:有重叠数据的数量窗口,设置方式举例:countWindow(5,3)
3.4 Watermark
我们知道,流处理从事件产生,到流经 source,再到 operator,中间是有一个过程和时间的,虽然大部分情况下,流到 operator 的数据都是按照事件产生的时间顺序来的,但是也不排除由于网络、背压等原因,导致乱序的产生,所谓乱序,就是指 Flink 接收到的事件的先后顺序不是严格按照事件的 Event Time 顺序排列的,所以 Flink 最初设计的时候,就考虑到了网络延迟,网络乱序等问题,所以提出了一个抽象概念:水印(WaterMark);
如上图所示,就出现一个问题,一旦出现乱序,如果只根据 EventTime 决定 Window 的运行,我们不能明确数据是否全部到位,但又不能无限期的等下去,此时必须要有个机制来保证一个特定的时间后,必须触发 Window 去进行计算了,这个特别的机制,就是 Watermark。
Watermark 是用于处理乱序事件的,而正确的处理乱序事件,通常用 Watermark 机制结合 Window 来实现。数据流中的 Watermark 用于表示 timestamp 小于 Watermark 的数据,都已经到达了,因此,Window 的执行也是由 Watermark 触发的。
Watermark 可以理解成一个延迟触发机制,我们可以设置 Watermark 的延时时长 t,每次系统会校验已经到达的数据中最大的 maxEventTime,然后认定 EventTime 小于 maxEventTime - t 的所有数据都已经到达,如果有窗口的停止时间等于 maxEventTime – t,那么这个窗口被触发执行。