这是我参与「第四届青训营 」笔记创作活动的第6天
流计算中的 Window 计算
01.概述
流式计算vs批式计算:
批处理:
T+1 离线计算模型:数据计算是天级别的,当天只能看到前一天的计算结果
小时级批计算:用一个小时的周期去模拟流式计算(很难做到)
实时计算:数据实时流动,实时计算,窗口结束直接发送结果,不需要周期调度任务。
处理时间: 数据在流式计算系统中真正处理时所在机器的当前时间。
事件时间: 数据产生的时间,比如客户端、传感器、后端代码报上数据时的时间。需要Watermark配合来处理乱序
02.Watermark
是什么?当前系统认为的事件时间所在的真实时间。
如何产生?一般是从数据的事件时间来产生,产生策略可以灵活多样。SQL/DataStream事件时间-5s/-20s
如何传递?
03.Window
典型的Window:滚动窗口、滑动窗口、会话窗口
Window的使用:
TUMBLE Window (滚动窗口)
这是最常见的窗口类型,就是根据数据的时间(可以是处理时间,也可以是事件时间)划分到它所属的窗口中windowStart = timestamp - timestamp % windowSize,这条数据所属的window就是[windowStart, windowStart + windowSize)
在我们使用window的过程中,最容易产生的一个疑问是,window的划分是subtask级别的,还是key级别的。这里大家要记住,Flink 中的窗口划分是key级别的。 比如下方的图中,有三个key,那每个key的窗口都是单独的。所以整个图中,一种存在14个窗口。
窗口的触发,是时间大于等于window end的时候,触发对应的window的输出(计算有可能提前就增量计算好了),目前的实现是给每个window都注册一个timer,通过处理时间或者事件时间的timer来触发window的输出。
HOP Window (滑动窗口)
了解了上面的TUMBLE窗口的基本原理后,HOP窗口就容易理解了。上面的TUMBLE窗口是每条数据只会落在一个窗口中。在HOP窗口中,每条数据是可能会属于多个窗口的(具体属于多少,取决于窗口定义的大小和滑动),比如下图中假设滑动是1h的话,那窗口大小就是2h,这种情况每条数据会属于两个窗口。除了这一点之外,其它的基本跟HOP窗口是类似的,比如也是key级别划分窗口,也是靠timer进行窗口触发输出。
SESSION Window (会话窗口)
会话窗口跟上面两种窗口区别比较大,上面两个窗口的划分,都是根据当前数据的时间就可以直接确定它所属的窗口。会话窗口的话,是一个动态merge的过程。一般会设置一个会话的最大的gap,比如10min。
那某个key下面来第一条数据的时候,它的window就是 [event_time, event_time + gap),当这个key后面来了另一条数据的时候,它会立即产生一个窗口,如果这个窗口跟之前的窗口有overlap的话,则会将两个窗口进行一个merge,变成一个更大的窗口,此时需要将之前定义的timer取消,再注册一个新的timer。
所以会话窗口要求所有的聚合函数都必须有实现merge。
迟到数据处理:
1.使用side output方式,把迟到的数据转变成一个单独的流,再由用户自己来决定如何处理这部分数据
2.直接drop掉
增量计算 VS 全量计算
增量计算: 每条数据到来后,直接参与计算(但是还不需要输出结果)
全量计算: 每条数据到来后,先放到一个buffer中,这个buffer会存储到状态里,直到窗口触发输出的时候,才把所有数据拿出来统一进行计算
EMIT触发:可以提前把窗口内容输出出来的一种机制。