这是我参与「第四届青训营 」笔记创作活动的第4天
实时计算
批式计算具备高准确性的特点,但是由于数据的实时性越高,价值越高,因此需要实时计算。
- 处理时间:数据在流式计算系统中真正处理所在机器的当前时间
- 事件时间:数据产生的时间
处理时间和事件时间之间可能存在gap,如果按照处理时间窗口,则窗口结束直接发送结果,不需要周期调度任务;如果按照事件时间窗口,则进入数据产生的窗口计算,可以有效处理数据延迟和乱序。
Watermark
在数据中插入watermark来表示当前的真实时间,可以发现数据的乱序和迟到。
Per-partition watermark
早期版本使用Per-subtask watermark生成机制,如果一个source subtask消费多个partition,多个partition之间的数据读取可能加剧乱序。
新版本引入了基于每个partition单独的watermark生成机制,有效避免partition之间的乱序问题。
Idle source
下游subtask会将上游subtask的watermark的最小值作为自己的watermark,如果有一个上游的watermark没更新,下游的都不会更新,引入Idle source后,当某个subtask断流超过配置的idle超时时间时,将当前subtask置为idle,下游在计算watermark时忽略是idle的subtask。
迟到数据
只有事件时间下才会产生迟到的数据,如果数据到来后,给数据划分的window的end比当前的watermark值小,说明这个窗口已经触发计算,系统认为这些是迟到的数据,算子自身决定如何处理:
- window聚合,默认丢弃迟到数据
- 双流join,如果是outer join,则可以认为它不能join到任何数据
- CEP,默认丢弃
Window
典型的Window有:
- 滚动窗口 Tumble Window:每条数据只属于一个窗口
- 滑动窗口 Sliding Window:每条数据可能属于多个窗口
- 会话窗口 Session Window:每条数据会单独划分一个窗口,如果窗口之间有交集则会合并
window对于迟到数据的处理:
- Allow lateness:设置一个允许迟到的时间,对于迟到的数据保留一个allow lateness时间,如果这段时间内继续到来数据,则继续之前的状态进行计算
- SideOutput:标记迟到数据,根据业务自行选择处理
EMIT
window如果较大,结果输出时间太久,可能失去实时计算的意义,EMIT输出就是在window结束之前提前输出部分计算结果。可以在DataStream中自定义Trigger来实现。
window优化
- mini-batch优化:小批量处理数据,避免频繁访问
- 倾斜优化:发生数据倾斜时对于数据先进行一次分区,提高计算效率
- distinct计算状态复用:通过用一个value表示多个state,减少状态数量
- pane优化:为避免频繁滑动数据重复参与计算,将滑动窗口滑动的量作为pane,每个窗口的计算结果为多个pane合并的结果,降低滑动窗口的状态存储量