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

117 阅读4分钟

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

记录一下今天的课程内容。

流计算和批计算的对比

批式计算

批计算,一般用于统计天级别的数据报表,如统计抖音昨天的日活跃度,需要昨天一天的数据来支撑,通常实际生产环境中一般使用Spark,Hive计算引擎,典型数仓模型架构为T+1架构,即输入数据计算,要等到第二天才能得到计算结果。

数据需要计算一天才能得到结果,如果在计算过程中遇到bug之类,第二天我们就很有可能得不到结果,想要减轻这种影响,简单的做法就是将天级别的数据分为更短的小时级别进行批处理。

image.png 但这样做在实际过程中,批计算需要不断的申请和调度数据库资源,不同时段数据的数仓模型也不一定相同,有时并不能按时完成任务,带来的开销也大,我们就需要采用别的方法来做到更实时,就到了流式计算的范畴。

流式计算

流式计算,也就是实时计算,引入了Window来处理,数据实时流动通过窗口,出窗口时计算出结果。

image.png 这样就会产生两个时间,处理时间(Processing Time)和事件时间(Event Time)

  • 事件时间:就是数据产生的时间。
  • 处理时间:数据真正处理时的时间,也就是经过我们的处理窗口Window的时间。

处理时间有时会延迟几分钟甚至几小时,如果我们想要用事件时间去计算数据所属窗口的结果,可以使用事件时间窗口。

image.png

这样把乱序和延迟的数据,在一定的容忍时间内归到同一个窗口,再进行计算和处理。但容忍时间并不好把握,我们就引入了Watermark来帮助判断。

Watermark

image.png 我们认为在Watermark左边小于它的数据就视为延迟数据,不参与事件计算,如在W(11)左边出现了时间为[8]的数据,就视为延迟数据过滤掉。

  • Watermark定义
    • 表示系统认为真实的事件时间

传递Watermark

image.png

与上节课程中Checkpoint的做法类似,上游将自己的Watermark值传递给下游,下游收到后进行一个判断,默认取Watermark数值更小的。

传递过程中的问题:

  • 上游subtask断流
    • 解决办法:设置一个idle时间(类似超时时间),当这个subtask不更新的时间超过idle时间时,就向下游发送idld状态,下游在计算Watermark值时,就可以忽略这个上游。

迟到数据处理

低于Watermark值的数据被视为迟到数据,一般默认丢弃,如果是双流join且是outer join则认为他join不到任何数据,除此之外还有2种处理方式

  • Allow lateness
    • 设置一个允许迟到的时间,窗口在计算完毕后并不会清除状态,而是等待一段时间,如果期间收到了延迟数据,就继续之前的状态计算。
  • SideOutput(侧输出流)
    • 对迟到数据打一个tag,在DataStream上获取这个数据流,根据业务的选择自行处理

Window

介绍完Watermark,我们来了解一下Window的主要组成

分类

典型的Window有3种:

  1. Tumble Window(滚动窗口)
  2. Sliding Window (滑动窗口)
  3. Session Window (会话窗口)
  • Tumble Window

image.png

在滚动窗口(Tumble Window)中,数据按照不同条件进行划分,如时间9:00-10:00是一个分类,每个用户都有他各自的窗口,像user 1就有window 1 ~ window 5,每个数据在进入他们的窗口时就可以开始计算,等到窗口时间结束后,再将结果统一输出

  • Sliding Window

image.png

在滑动窗口中(Sliding Window)中,就相当于滚动窗口添加了一个滑动时间,比如9:00-11:00的窗口,向后滑动一小时,那就是10:00-12:00的窗口,相比滚动窗口,这样不同滑动窗口之间会有数据的重复。

  • Session Window

image.png

在会话窗口(Session Window)中,窗口的大小是动态变化的,每个数据单独划分成一个窗口,遇到有交集的数据则合并并扩容,比如现在的窗口是10:20-10:30,在移动过程中,发现了一个大小为10:25-10:35的窗口,这两个窗口之间有交集,我们就可以将他们合并,并更新窗口大小为10:20-10:35。