这是我参与「第四届青训营 」笔记创作活动的第5天。
第四节课「流计算中的 Window 计算」的内容主要包含 4 个方面:概述、Watermark、Window、案例分析。这篇文章为 Window 的相关内容。
Window 分类
Tumble Window(滚动窗口)
-
窗口划分:
- 每个key单独划分
- 每条数据只会属于—个窗口
-
窗口触发:Window结束时间到达的时候一次性触发
最常见的窗口类型,就是根据数据的时间(可以是处理时间,也可以是事件时间)划分到它所属的窗口中windowStart = timestamp - timestamp % windowSize,这条数据所属的window就是[windowStart, windowStart + windowSize)
Sliding Window(滑动窗口)
- 窗口划分:
- 每个key单独划分
- 每条数据可能会属于多个窗口(具体属于多少,取决于窗口定义的大小和滑动)
窗口触发:Window结束时间到达的时候一次性触发
Session Window(会话窗口)
-
窗口划分:
- 每个key单独划分
- 每条数据会单独划分为一个窗口,如果window之间有交集,则会对窗口进行merge
-
窗口触发:Window结束时间到达的时候一次性触发
一个动态merge的过程:一般会设置一个会话的最大的gap,当某个key下面来第一条数据的时候,它的window就是 [event_time, event_time + gap),当这个key后面来了另一条数据的时候,它会立即产生一个窗口,如果这个窗口跟之前的窗口有overlap的话,则会将两个窗口进行一个merge,变成一个更大的窗口。
迟到数据处理
-
迟到数据的定义:根据watermark的原理,watermark驱动某个窗口触发输出之后,这个窗口如果后面又来了数据,那这种情况就属于是迟到的数据了。(注:不是数据的时间晚于watermark就算是迟到,而是它所属的窗口已经被触发了才算迟到)。
-
产生迟到数据的情况:只有事件时间下才会有迟到数据
-
迟到数据的处理:
- 使用side output方式,把迟到的数据转变成一个单独的流,再由用户自己来决定如何处理这部分数据
- 直接drop掉
注:side output只有在DataStream的窗口中才可以用,在SQL中目前还没有这种语义,所以暂时只有drop这一个策略。
增量计算 VS 全量计算
增量计算
- 每条数据到来后,直接进行计算,window只存储计算结果
- reduce, aggregate 等函数是增量计算
- SQL 中的聚合只有增量计算
全量计算
- 每条数据到来后,会存储到window的state中,等到window触发计算的时候,再将所有数据拿出来一起计算
- process 函数是全量计算
EMIT触发
背景:通常来讲,window都是在结束的时候才能输出结果,比如1h的 tumble window,只有在1个小时结束的时候才能统一输出结果。如果窗口比较大,比如1h或者1天,甚至于更大的话,那计算结果输出的延迟就比较高,失去了实时计算的意义。
-
EMIT输出:在window没有结束的时候,提前把window计算的部分结果输出出来。
-
实现
- 在DataStream里面可以通过自定义Trigger来实现,Trigger的结果可以是 CONTINUE、FIRE(触发计算,但是不清理)、PURGE、FIRE_AND_PURGE
- SQL也可以使用,通过配置:
table.exec.emit.early-fire.enabled=true table.exec.emit.early-fire.delay={time}
个人总结
了解了 Window的分类、迟到数据处理、增量计算和全量计算的区别、EMIT触发。