这是我参与「第四届青训营 」笔记创作活动的的第3天
流计算中的 Window 计算
1.概述
流式计算 vs 批式计算: 实时性越高,数据价值越高
| 特性 | 批式计算 | 流式计算 |
|---|---|---|
| 数据存储 | HDFS Hivs | Kafka Pulsar |
| 时效性 | 天 | 分钟 |
| 准确性 | 精确 | 精确和时效 |
| 计算引擎 | Hive Spark Flink | Flink |
| 模型 | Exactly-once | at-least-once Exactly-once |
| 资源模型 | 定时调度 | 长期持有 |
| 主要场景 | 离线 | 实时数仓、实时风控 |
- 实时计算:处理时间窗口
数据实时流动、实时计算,窗口结束直接发送结果,不需要周期调度任务 - 事件时间:数据产生的时间
- 处理时间:数据在流式中真正处理的时间
- 窗口结束:事件时间延迟不定
2.Watermark
- def:表示系统认为的当前真实的事件时间(简单而言,就是数据产生时间而不是处理时间)
- SQL语法: 多个watermark取最小值
CREATE TABLE Orders(
user BIGINT,
product STRING,
order_time TIMESTAMP(3),
WATERMARK FOR order_time AS order_time - INTERVAL '5' SECOND
)WIth(...);
- 问题:
- per-partition VS per-subtask watermark生成
per-subtask:早期版本,多个partiton之间数据可能会加剧乱序程度;
per-partition:更为高效。 - 部分partition/subtask断流
上游有subtask的watermark不更新,下游的watermark(取最小值)都不更新。
解决方法:
Idle source:subtask断流超过idle设定时间时,将subtask标记为idle,并下发一个idle状态给下游,下游在配置watermark时可以忽略idle的subtask - 迟到数据处理
迟到数据:晚于watermark到来的数据- window 聚合,默认丢弃
- 双流join,outerjoin则可以认为不能join到任何数据
- CEP,默认丢弃
- per-partition VS per-subtask watermark生成
3.Window
- window 分类:
- Tumble window 滚动窗口
- 窗口划分:每个key单独划分,每条数据只会属于一个窗口;
- 窗口触发:结束时间到达的时候一次性触发。
- Sliding window 滑动窗口
- 窗口划分:每个key单独划分,每条数据会属于多个窗口;
- 窗口触发:结束时间到达的时候一次性触发。
- Session window 会话窗口
- 窗口划分:每个key单独划分,每条数据会单独划分为一个窗口,如果window之间有交集,则会对窗口进行merge
(eg 10:30-10:40 & 10:35-10:45 -> 10:30 - 10:45) - 窗口触发:结束时间到达的时候一次性触发。
- 窗口划分:每个key单独划分,每条数据会单独划分为一个窗口,如果window之间有交集,则会对窗口进行merge
- Tumble window 滚动窗口
- window 使用:SQL API
SELECT
user,
TUMBLE_START(order_time,INTERCAL '1' DAY) AS wStart,
SUM(amount) FROM Orders
GROUP BY
TUMBLE(order_time, INTERVAL '1' DAY),
user
- 迟到数据处理
- 迟到:数据晚于watermark(一般),数据晚于watermark且属于的窗口已触发(window)只有在事件时间下会有迟到的数据
- 默认处理:丢弃
- 特别处理:
- Allow lateness:
- 设置允许迟到的时间,正常计算结束后不会清理状态,保留allow Lateness的时间,数据到来会继续之前的状态进行计算
- 修正过程实则为Retract的过程,保证最终语义一致性
- 适用范围:DataStream、SQL
- SideOutput(侧输出流):
- 迟到数据打tag,根据tag获取迟到数据流,根据业务层面自行选择处理
- 适用范围:DataStream
- Allow lateness:
- 窗口计算模型
- 增量计算:
- 每来条数据直接进行计算,只储存计算结果,不保留数据;
- 典型的reduce、aggregate等函数;
- SQL的聚合只有增量计算。
- 全量计算:
- 每条数据到来会存储到state。等到window触发计算时候,所有数据拿出来一起计算;
- 典型的process函数就是全量计算。
- 增量计算:
- EMIT 触发
允许中间结果可以输出多次,即window没有结束的时候,提前把window计算的部分结果输出出来- 实现方式:
- DataStream
通过自定义trigger实现,如CONTINUE、FIRE(触发计算,但不清理)、PURGE、FIRE_AND_PURGE - SQL 配置
table.exec.emit.early-fire.enabled=true
table.exec.early-fire.delay={time}
- DataStream
- 实现方式:
高级优化
- mini-batch
优化解决频繁访问状态的问题
- 多条数据一次性读、处理、写
- 上游添加assigner,开启一个新的minibatch,之前buffer数据输出
- 倾斜优化(local - global)
优化解决倾斜的问题
- 问题原因:eg 对不同数据分别进行求和,可能某一类数据量大,而另一类少
- 预聚合,上游先进行一定的操作,再聚合
- Distinct 计算状态复用
降低状态量
- 利用value作为long数据类型(64bit)表征数据是否来到,eg01100。
- Pane优化
优化降低滑动窗口状态储存量\
- 滑动窗口在每一个窗口中计算,数据属于多个窗口,计算量大。
- 结局方案:设置pane定时计算,输出时多个pane先merge再输出
4.案例分析
- 使用Flink SQL 计算抖音的日活曲线\
- 方法一:使用滚动窗口,提前EMIT输出
SELECT COUNT(DISTINCT uid) as dau TUMBLE_START(event_time, INTERVAL '1' DAY) as wstart, LOCALTIMESTAMP AS current_ts FROM user_activity GROUP BY TUMBLE(event_time,INTERVAL '1' DAY) table.exec.emit.early-fire.enabled=true table.exec.emit.early-fire.delay=5min- problem:所有数据在一个subtask窗口,无法并行
- 改进:两阶段聚合来把数据打散,完成第一轮聚合,第二轮聚合只需要对各个分桶的结果求和即可
SELECT SUM(partial_cnt) as dau TUMBLE_START(event_time, INTERVAL '1' DAY) as wstart, LOCALTIMESTAMP AS current_ts FROM( SELECT COUNT(DISTINCT uid) as partial_cnt, TUMBLE(event_time,INTERVAL '1' DAY) as event_time FROM user_activity GROUP BY TUMBLE(event_time, INTERVAL, '1' DAY) MOD(UID,10000) #根据uid分成10000个桶 ) GROUP BY TUMBLE(event_time,INTERVAL '1' DAY) table.exec.emit.early-fire.enabled=true table.exec.emit.early-fire.delay=5min table.exec.window.allow-retract-input=true - 计算大数据任务的资源使用\
- 大数据离线任务运行时通常会有多个container启动并运行,每个container运行结束时,YARN负责将他的资源使用(CPU、内存)情况上报。需要根据YARN上报的各个container的信息,在任务结束时,尽快的算出一个任务运行所消耗的总资源。
- 通过会话窗口数据划分到一个window,再结果求和
SELECT
application_id
SUM(cpu_usage) as cpu_total
SUM(memory_usage) as memory_total
FROM resource_usage
GROUP BY
application_id,
SESSION(event_time, INTERVAL '10' MINUTE)
Conclusion
- 学习了流式计算的基本概念
- 学习了watermark的生成运行方式,其中有关迟到数据、watermark的生成方式及数据断流进行了进一步的拓展
- 学习了window的基本分类,以及迟到数据处理、增量or全量计算、EMIT输出的概念和实现方式
- 学习了四种高级优化:local-global、mini-batch、distinct计算状态复用、pane优化