一、Time
Flink主要是做流式计算,数据是通过滚动(rolling)过来的,就像溪流一样,源源不断地进来。原文Windows are at the heart of processing infinite streams. Windows split the stream into “buckets” of finite size, over which we can apply computations. 也就是说,window将无限的数据流切割成有限数据集,然后运用各种operators做业务逻辑运算。分为Keyed window和Non-Keyed window两种结构,Non-Keyed的window算子一般是以All作为后缀。
Flink支持三种Time:
1、Event Time:事件实际产生的时间,在进入Flink前就已经存在,且必须指定watermark的生成方式
2、Ingestion Time:摄取事件,也就是刚进入Flink source的时间
3、Processing Time:执行算子操作机器的当前系统时间(每个算子都不一样)
Time的设置:默认是ProcessingTime,如果使用Event time,source之后还需要指定Timestamp Assigner和Watermark
实时系统中,由于网络等各种原因造成的数据延时颇为常见,造成事件发送到Flink的事件晚于事件本身产生的时间。如果基于event time构建window,对于late element,不能无限期等待下去,必须有个机制保证一定的时间后,必须触发window去进行计算,这个特殊的机制,就是watermark。关于水位线watermarker,推荐博文:Flink WaterMark 详解
关于time和watermark,举一个生活中的例子,考试。考试规定9:00--11:00考语文,14:00--16:30考数学,迟到15分钟就不让进考场。那么9:00就是一个watermark,告诉系统,9:00该来的考生(数据)都来了,可以开考了(触发计算);然后继续等待下一个watermark 14:00,告诉系统,新的一批数据(考生)来了,又可以开考了(触发计算)。15分钟就是一个延迟值,超过延时值再来的数据会被果断丢弃;而在延时值之间到来的数据,有不同的处理策略,比如可以同样处理,但记录,如果通过监控发现延时值数据太多,就要分析原因。
两种Watermark
Periodic Watermark:ExecutionConfig.setAutoWatermarkInterval(msec)(默认是200ms,设置watermark设置的周期),实现AssignerWithPeriodicWatermarks接口。
Puncuated Watermark:基于某些事件触发watermark的生成和发送(由用户代码实现,例如遇到特殊元素),实现AssignerWithPuncuatedWatermarks接口。
二、Windows
创建:属于改窗口的第一个元素到达时就会创建改窗口。
销毁:time-base 当时间超过窗口的结束时间戳+指定时延AllowedLateness,窗口将被移除;count-base 当足够数量的element到来时,窗口将会被移除。
第一种划分法:根据基于Count和Time
1、Count-base Windows
1.1 Count Tumbling-windows
1.2 Count Sliding-windows
1.3 Global windows
2、Time-base Windows
2.1 Time Tumbling-window
2.2 Time Sliding-window
2.3 Time Session-windows
2.4 Global windows
第二种划分法:Tumbling翻滚、Sliding滑动、Session会话、Global全局
1、Tumbling-window
每一段时间窗口的时长都是相同的,不管这个时间窗口内有无数据、数据多寡,都会准时开启和关闭,时间设置是左闭右开,比如我们设置的时长是5min,则:
[00:00:00 -- 00:04:59]
[00:05:00 -- 00:09:59]
[00:10:00 -- 00:14:59]
---------
2、Sliding-window
滑动窗口在不同的窗口之间,会有一部分的重叠overlap,比如设置时长10min,slide-time 5min,则:
[00:00:00 -- 00:09:59]
[00:05:00 -- 00:14:59]
[00:10:00 -- 00:19:59]
---------
3、Session-windows
类似于Web项目中的session,设置一定gap size,当超过gap size时间没有数据过来,就销毁当前时间,一直等到下一个数据到来再创建新的时间窗口。
4、Global windows
用在自定义触发器Trigger的场景
2.3 windowAssinger
windowAssinger窗口分配器:负责将每个传入的元素分配给一个或多个窗口。keyStream是window,Non-Key Stream是windowAll。分类参考2.1
count-based window和Time-based window
总结:
三、窗口函数
在定义了窗口分配器之后,需要为每一个窗口明确指定计算逻辑,这就是窗口函数要做的事情。当系统决定一个窗口已经准备好执行之后,这个窗口函数将被用来处理窗口中的每一个元素(可能是分组的)。
3.1 ReduceFunction
输出:
3.2 AggregateFunction
输出:
3.3 ReduceFunctionOnWindowAll
输出:
3.4 ProcessWinFuntion
输出:
四、Trigger和Evictor
4.1 Trigger触发器
指定窗口函数在什么条件下可被触发,还可以决定创建和删除窗口之间的任何时间清除窗口的内容。仅限于清除窗口中元素,而不是元数据,这意味着新数据依然可以添加到窗口中。例如当窗口的数据达到5个时,或水位线watermark达到窗口边界时触发计算。
4.2 Evictor驱逐者
将在触发器之后或者在函数被应用前后,清除窗口中的元素。
4.3 延时Lateness
Flink源码:https://github.com/apache/flink
Flink官网:https://ci.apache.org/projects/flink/flink-docs-release-1.12/