这是我参与「第四届青训营 」笔记创作活动的第2天
1概述
实时计算:事件时间的窗口,数据实时进入到真实事件发生的窗口中进行计算,可以有效的处理
-
数据价值:实时性越高,数据价值越高
-
批式计算一般是T+1 的数仓架构,即数据计算是天级别的,当天只能看到前一天的计算结果。通常使用的额计算引擎是Hive或者spark。计算的时候数据是完全ready的,输入输出确定。离线计算模型
-
为了能够做到更实时,需要支持小时级的批计算出现
-
处理时间窗口:
- 实时计算:提供一个处理时间窗口
- 数据的实时流动,实时计算,窗口结束直接发送结果,不需要周期调度任务
-
实时计算分为处理时间和事件时间
- 处理时间:数据在流式计算系统中真正处理时所在机器的当前时间
- 事件时间:数据产生的时间,比如客户端,传感器,后端代码上报数据时的时间
-
事件时间窗口:
- 数据实时进入到真实事件发生的窗口中进行计算,可以有效的处理数据延迟和乱序
-
事件时间窗口需要watermark配合处理乱序
- 在数据中插入一些watermark,来表示当前真实时间
- 在数据存在乱序的时候,用来在乱序容忍和实时性之间做一个平衡
Exactly-Once/At-Least-Once
2. Watermark
Watermark定义:当前系统认为的事件时间所在的真实时间。
Watermark产生:一般是从数据的事件时间来产生,产生策略可以灵活多样,最常见的包括使用当前事件时间的时间减去一个固定的delay,来表示可以可以容忍多长时间的乱序。
Watermark传递:取上游所有subtask的最小值
实际操作中的问题
-
观察一个任务中的watermark是多少,是否是正常的
- Flink Web UI上的信息来观察当前任务的watermark情况
-
Per-partition / Per-subtask 生成watermark的优缺点
- 后期就逐步的变成了per-partition的方式来产生watermark,来避免多个partition被消费之后因为消费速度不同而产生的数据乱序问题。
- 如果有部分partition/subtask会断流,应该如何处理——Idle source
- 算子对于时间晚于watermark的数据的处理
- 对于迟到数据,一般默认丢弃
3. Window
3.1 Window 使用
SQL和Datastream两种方法
3.2 Window 分类
典型的Window:Tumble/Sliding/Session
其他Window:全局/Count/累计
-
TUMBLE Window (滚动窗口)
- 根据时间划分窗口,Flink中窗口划分是key级别的
- 窗口的触发,是时间大于等于window end的时候,触发对应的window的输出
-
HOP Window (滑动窗口)
- 每条数据可能会属于多个窗口,取决于窗口定义的大小和华东
-
SESSION Window (会话窗口)
- 动态窗口,有merge的操作
3.2.1 迟到数据处理
迟到定义:watermark驱动某个窗口触发输出之后,这个窗口如果后面又来了数据,那这种情况就属于是迟到的数据了。(注意,不是数据的时间晚于watermark就算是迟到,而是它所属的窗口已经被触发了,才算迟到)
产生时间:只有事件时间下才会有吃到的数据
处理方式:
- Allow latenes 设置允许迟到时间,适用于SQL和Datastream
- SideOutPut 对迟到数据打tag,业务层自行处理,适用于Datastream
3.2.2 增量计算&全量计算
增量计算
- 每条数据到来,直接进行计算,window置存储计算结果。例如reduce和aggregate函数 全量计算
- 每条数据到来,会存储到window中的state里,等待window一起触发计算。例如process函数
3.2.3 EMIT输出
在window没有结束的时候提前把window计算的部分结果输出出来。DataStream可以使用tigger触发器;SQL可以通过配置
3.3 Window 高级优化
- Mini-batch 优化解决频繁访问状态的问题
- local-global优化解决倾斜问题
- Distinct状态复用降低状态量
- Pane优化降低滑动窗口的状态存储量
4. 案例分析
- 抖音日活曲线
做法:通过一个滚动窗口,计算DAU。开一个Emit能够实时输出。通过两阶段聚合来把数据打散,完成第一轮聚合,第二轮聚合只需要对各个分桶的结果求和即可(这样能够解决倾斜问题,所有数据都需要在一个subtask中完成窗口计算,无法并行)。 - 计算大数据任务资源的使用
做法:可以通过会话窗口来将数据划分到一个window中,然后将结果求和