流计算中的 Window 计算(2) | 青训营笔记

107 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的第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触发。

参考