概述
流式计算 V.S. 批式计算
批处理(批计算)
T+1(天)
(小时批级计算)
处理时间窗口
处理时间 V.S. 事件时间
实时计算的难点:
- 事件到达一般会有延迟
- 事件时间一般不可控
- 事件到达乱序
事件时间窗口
watermark
可以识别出延时到来的数据
小结
定义
系统认为的当时的时间
watermark的产生
watermark的传递
- 每个算子接收上游的watermark,watermark的最小值为它的数值
- 每个算子向下游传递它的watermark
可以通过Flink UI观察watermark
容易遇到的问题
典型问题一
如上图,一个source可能消费两个partition,但两个partition拿到/处理数据的时间可能不同。同一个watermark被不同的partition传到下游时,可能有更严重的乱序
典型问题二
数据少的时候不能产生watermark,例如:白天有数据,晚上没数据
典型问题三
小结
window
介绍
分类
- tumble window 滚动窗口
- sliding window 滑动窗口
- session window 会话窗口
window的使用
右侧的图中,越高,用户的使用成本越低,能表达的语义越少
滚动窗口
- 窗口大小相同
- 窗口的任意时刻可以输入,窗口的结束时间才可以输出
- 窗口之间没有重叠
滑动窗口
- 窗口大小相同
会话窗口
- 窗口的划分是一个动态的过程
常见问题的处理
迟到数据的处理
增量计算 VS 全量计算
allow lateness的时间内其实是在修正(相当于retract机制)
增量计算的好处:
- 使用的存储空间少
- 计算的更快
EMIT触发
- 通常,窗口的大小比较大,我们希望不光在窗口结束时输出
- 提前输出,之后再retract修改之前的输出即可
window的高级优化
Mini-batch优化
问题:算子会保存state,即每个用户的访问次数。访问state会非常频繁。
措施:攒一小批数据,一起访问state,再一起写state
新的问题:生产中,算子之间的拓扑关系可能十分复杂,这样批处理的方式会导致很长的延时。
倾斜优化 local-global
Distinct状态复用
- 常见操作:先进行filter再进行聚合计算
- 一般情况下,distinct被优化成group by+后续操作,在这在window中不现实,因为每个window会变得很复杂。此外,在window中,针对之前window的每个count还要保存一个state,看之前某条数据是否出现过。
- 策略:将每个count的state压在一起(类似于一个stack,用int或long int存储),这样可以直接复用其他count的state(比如最后一个filter可以复用前面一些filter的state)
pane优化
问题:在滑动窗口的情况下,大量数据可能被重复计算
措施:窗口结束时,并不急着计算,而是把它划分成比overlap时间更小的窗口(pane),每个pane只计算一次,避免多次计算
案例分析
案例一 使用Flink SQL计算抖音的日活曲线
策略:使用一个时长为一天的滚动窗口,在窗口中count distinct,并采用EMIT输出
策略:分桶再聚合(典型的倾斜优化)