这是我参与「第四届青训营 」笔记创作活动的的第6天
记录一下今天的课程内容。
流计算和批计算的对比
批式计算
批计算,一般用于统计天级别的数据报表,如统计抖音昨天的日活跃度,需要昨天一天的数据来支撑,通常实际生产环境中一般使用Spark,Hive计算引擎,典型数仓模型架构为T+1架构,即输入数据计算,要等到第二天才能得到计算结果。
数据需要计算一天才能得到结果,如果在计算过程中遇到bug之类,第二天我们就很有可能得不到结果,想要减轻这种影响,简单的做法就是将天级别的数据分为更短的小时级别进行批处理。
但这样做在实际过程中,批计算需要不断的申请和调度数据库资源,不同时段数据的数仓模型也不一定相同,有时并不能按时完成任务,带来的开销也大,我们就需要采用别的方法来做到更实时,就到了流式计算的范畴。
流式计算
流式计算,也就是实时计算,引入了Window来处理,数据实时流动通过窗口,出窗口时计算出结果。
这样就会产生两个时间,处理时间(Processing Time)和事件时间(Event Time)
- 事件时间:就是数据产生的时间。
- 处理时间:数据真正处理时的时间,也就是经过我们的处理窗口Window的时间。
处理时间有时会延迟几分钟甚至几小时,如果我们想要用事件时间去计算数据所属窗口的结果,可以使用事件时间窗口。
这样把乱序和延迟的数据,在一定的容忍时间内归到同一个窗口,再进行计算和处理。但容忍时间并不好把握,我们就引入了Watermark来帮助判断。
Watermark
我们认为在Watermark左边小于它的数据就视为延迟数据,不参与事件计算,如在W(11)左边出现了时间为[8]的数据,就视为延迟数据过滤掉。
- Watermark定义
- 表示系统认为真实的事件时间
传递Watermark
与上节课程中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种:
- Tumble Window(滚动窗口)
- Sliding Window (滑动窗口)
- Session Window (会话窗口)
- Tumble Window
在滚动窗口(Tumble Window)中,数据按照不同条件进行划分,如时间9:00-10:00是一个分类,每个用户都有他各自的窗口,像user 1就有window 1 ~ window 5,每个数据在进入他们的窗口时就可以开始计算,等到窗口时间结束后,再将结果统一输出
- Sliding Window
在滑动窗口中(Sliding Window)中,就相当于滚动窗口添加了一个滑动时间,比如9:00-11:00的窗口,向后滑动一小时,那就是10:00-12:00的窗口,相比滚动窗口,这样不同滑动窗口之间会有数据的重复。
- Session Window
在会话窗口(Session Window)中,窗口的大小是动态变化的,每个数据单独划分成一个窗口,遇到有交集的数据则合并并扩容,比如现在的窗口是10:20-10:30,在移动过程中,发现了一个大小为10:25-10:35的窗口,这两个窗口之间有交集,我们就可以将他们合并,并更新窗口大小为10:20-10:35。