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

117 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的第3天

流式计算

  • 实时计算的处理时间窗口:数据实时流动实时计算,窗口结束就提交数据。
  • 处理时间:数据在流式计算系统中真正处理时所在机器的当前时间
  • 事件时间:数据产生的时间,比如客户端、传感器、后端代码等上报数据时的时间
  • Watermark(水位线):衡量事件真实时间的标记(一般周期性生成)

Watermark原理

系统认为的当前真实的事件时间,一般从数据的事件时间来产生。常见的包括使用当前事件时间减去一个固定的delay,来表示可以容忍多长时间的乱序

如何传递

  • 1对1:遇大于当前Watermark则更新

  • 多对1:取上游所有Watermark的的最小值且大于当前Watermark

问题

per-partition vs per-subtask watermark 生成

  • Flink里早期是per-subtask机制。典型问题是如果一个source task消费多个partition,那么多个partition之间的数据可能会因为消费的速度不同,加剧数据的乱序程度。
  • 新版本引入了每个partition单独的watermark生成机制,可以有效避免以上情况

部分partition/subtask断流

如果上游有一个subtask的watermark不更新了,则下游的watermark都不更新。

-> 解决方式:idle source

迟到数据处理

算子自身来决定如何处理迟到数据

  • Window聚合,默认会丢弃迟到数据
  • 双流join,如果是outer join,则可以认为它不能join到任何数据
  • CEP,默认丢弃

Window

分类

  1. Tumble Window(滚动窗口)

    • 窗口划分:每个key单独划分,每条数据只会属于一个窗口。
    • 窗口触发:window结束时间到达的时候一次性触发
  2. Session Window(会话窗口)

    • 窗口划分:每个key单独划分,每条数据会单独划分为一个窗口,如果window之间有交集,则会对窗口进行merge
    • 窗口触发:window结束时间到达的时候一次性触发
  3. Sliding Window(滑动窗口):

    • 窗口划分:每个key单独划分,数据可能属于多条窗口。

    • 窗口触发:Window结束时间到达的时候一次性触发。

迟到的数据处理:默认丢弃

  1. Allow lateness:设置一个允许迟到的时间,保留 allowl ateness 一定的时间,继续对之前的状态进行计算。

    • 适用于: DataStream. SQL
  2. SideOutput (侧输出流):对迟到数据打一个tag ,然后在DataStream上根据这个tag获取到迟到数据流,然后业务层面自行选择进行处理。适用于,DataStream。

增量 vs 全量计算

  • 增量计算:每条数据到来,直接计算,window只存储计算结果(e.g. reduce、aggregate函数)
  • 全量计算:每条数据到来,会存储到window到state,等到窗口触发计算的时候,才把所有数据拿出来一起计算(e.g. process函数)

EMIT输出

在window没有结束的时候提前把window计算的部分结果输出出来。

  • 在DataStream里面可以通过自定义Trigger来实现。