四、【计算】流计算中的Window计算(下) | 青训营笔记

简介: 四、【计算】流计算中的Window计算(下) | 青训营笔记

👉引言💎


学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。 热爱写作,愿意让自己成为更好的人............

铭记于心
🎉✨🎉我唯一知道的,便是我一无所知🎉✨🎉


四、Window 高级优化


  • 注意:以下所有的高级优化,都只限于在SQL中的window中才有;在DataStream中,用户需要自己通过代码来实现类似的能力


1 Mini-batch


image.png

一般来讲,Flink的状态比较大一些都推荐使用rocksdb statebackend,这种情况下,每次的状态访问就都需要做一次序列化和反序列化,这种开销还是挺大的。为了降低这种开销,我们可以通过降低状态访问频率的方式来解决,这就是mini-batch最主要解决的问题:即赞一小批数据再进行计算,这批数据每个key的state访问只有一次,这样在单个key的数据比较集中的情况下,对于状态访问可以有效的降低频率,最终提升性能。

这个优化主要是适用于没有窗口的聚合场景,字节内部也扩展了window来支持mini-batch,在某些场景下的测试结果可以节省20-30%的CPU开销。

mini-batch看似简单,实际上设计非常巧妙。假设用最简单的方式实现,那就是每个算子内部自己进行攒一个小的batch,这样的话,如果上下游串联的算子比较多,任务整体的延迟就不是很容易控制。所以真正的mini-batch实现,是复用了底层的watermark传输机制,通过watermark事件来作为mini-batch划分的依据,这样整个任务中不管串联的多少个算子,整个任务的延迟都是一样的,就是用户配置的delay时间。

下面这张图展示的是普通的聚合算子的mini-batch原理,window的mini-batch原理是一样的。

image.png


2 Local-global


local-global优化是分布式系统中典型的优化,主要是可以降低数据shuffle的量,同时也可以缓解数据的倾斜。

所谓的local-global,就是将原本的聚合划分成两阶段,第一阶段先做一个local的聚合,这个阶段不需要数据shuffle,是直接跟在上游算子之后进行处理的;第二个阶段是要对第一个阶段的结果做一个merge(还记得上面说的session window的merge么,这里要求是一样的。如果存在没有实现merge的聚合函数,那么这个优化就不会生效)。

如下图所示,比如是要对数据做一个sum,同样颜色的数据表示相同的group by的key,这样我们可以再local agg阶段对他们做一个预聚合;然后到了global阶段数据倾斜就消除了。

image.png


3 Distinct状态复用


对于distinct的优化,一般批里面的引擎都是通过把它优化成aggregate的方式来处理,但是在流式window中,我们不能直接这样进行优化,要不然算子就变成会下发retract的数据了。所以在流式中,对于count distinct这种情况,我们是需要保存所有数据是否出现过这样子的一个映射。

在SQL中,我们有一种方式可以在聚合函数上添加一些filter,如下面的SQL所示:

image.png

像这种情况,我们会对同一个字段用不同的filter来进行count distinct的计算。如果每个指标都单独用一个map来记录每条数据是否出现过,那状态量是很大的。

我们可以把相同字段的distinct计算用一个map的key来存储,在map的value中,用一个bit vector来实现就可以把各个状态复用到一起了。比如一个bigint有64位,可以表示同一个字段的64个filter,这样整体状态量就可以节省很多了。

image.png


4 滑动窗口pane复用


滑动窗口如上面所述,一条数据可能会属于多个window。所以这种情况下同一个key下的window数量可能会比较多,比如3个小时的窗口,1小时的滑动的话,每条数据到来会直接对着3个窗口进行计算和更新。这样对于状态访问频率是比较高的,而且计算量也会增加很多。

优化方法就是,将窗口的状态划分成更小粒度的pane,比如上面3小时窗口、1小时滑动的情况,可以把pane设置为1h,这样每来一条数据,我们就只更新这条数据对应的pane的结果就可以了。当窗口需要输出结果的时候,只需要将这个窗口对应的pane的结果merge起来就可以了。

注意:这里也是需要所有聚合函数都有merge的实现的

image.pngimage.png


5 总结


  1. Mini-batch优化解决频繁访问状态的问题
  2. local-global 优化解决倾斜问题
  3. Distinct状态复用降低状态量
  4. Pane 优化降低滑动窗口的状态存储量


五、案例分析


案例一:计算实时抖音日常去重活跃用户数(DAU)曲线


DAU(Daily Active User):指的是每天的去重活跃用户数

输出:每个5s更新一下当前的DAU数值,最终获得一天内的DAU变化曲线

要求:通过上面课程中学到的窗口的功能以及相关的优化,开发一个Flink SQL任务,使得可以高效的计算出来上面要求的实时结果。

  • 问题分析:
    所有数据都需要在一个subtask中完成窗口计算,无法并行
  • 解决方案:

image.pngimage.png
table.exec.window.allow-retract-input=true
通过两阶段聚合来把数据打散,完成第一轮聚合,第二轮聚合只需要对各个分桶的结果求和即可。


案例二:计算大数据任务的资源使用


问题描述:大数据任务(特指离线任务)运行时通常会有多个container启动并运行,每个container在运行结束的时候,YARN会负责将它的资源使用(CPU、内存)情况上报。一般大数据任务运行时间从几分钟到几小时不等

需求:根据YARN上报的各个container的信息,在任务结束的时候,尽快的计算出一个任务运行所消耗的总的资源。假设前后两个container结束时间差不超过10min

image.png

典型的可以通过会话窗口来将数据划分到一个window中,然后再将结果求和即可


问题


  1. 复习实时计算产生的背景,与离线计算最主要的区别,以及流式窗口计算的最大挑战
  2. watermark的产生、传递、使用原理,以及在各种断流或者上游出现问题的情况下应该如何处理
  3. 三种基本的window的功能和原理
  4. window的基本功能扩展有哪些
  5. 四种高级的window的优化分别是为了解决什么问题,又是什么原理

🌹写在最后💖: 路漫漫其修远兮,吾将上下而求索!伙伴们,再见!🌹🌹🌹

相关文章
|
2月前
|
消息中间件 SQL Apache
实时计算 Flink版产品使用合集之想要解决RangeMap在处理重叠范围时的裁开问题如何解决
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
SQL 分布式计算 大数据
四、【计算】流计算中的Window计算(上) - 青训营笔记
四、【计算】流计算中的Window计算(上) - 青训营笔记
四、【计算】流计算中的Window计算(上) - 青训营笔记
|
SQL 存储 Unix
四、【计算】流计算中的Window计算(中) | 青训营笔记
四、【计算】流计算中的Window计算(中) | 青训营笔记
四、【计算】流计算中的Window计算(中) | 青训营笔记
|
SQL 存储 Unix
流式计算中的 Window 计算|青训营笔记
介绍实时计算中的Watermark概念,以及如何产生、传递,还有一些典型的生产实践中遇到的问题;介绍三种最基本的window类型,以及他们的实现原理;同时会结合业务场景介绍一些高级优化的功能和原理
198 0
流式计算中的 Window 计算|青训营笔记
|
存储 分布式计算 大数据
二、【计算】流|批|OLAP一体 的Fllink引擎 (上)| 青训营笔记
二、【计算】流|批|OLAP一体 的Fllink引擎 (上)| 青训营笔记
二、【计算】流|批|OLAP一体 的Fllink引擎 (上)| 青训营笔记
|
SQL 分布式计算 大数据
七、【计算】Presto架构原理与优化介绍(上) | 青训营笔记
七、【计算】Presto架构原理与优化介绍(上) | 青训营笔记
七、【计算】Presto架构原理与优化介绍(上) | 青训营笔记
|
存储 SQL 算法
三、【计算】Exactly Once 语义在Flink中的实现(上) | 青训营笔记
三、【计算】Exactly Once 语义在Flink中的实现(上) | 青训营笔记
三、【计算】Exactly Once 语义在Flink中的实现(上) | 青训营笔记
|
存储 消息中间件 关系型数据库
三、【计算】Exactly Once 语义在Flink中的实现(下) | 青训营笔记
三、【计算】Exactly Once 语义在Flink中的实现(下) | 青训营笔记
三、【计算】Exactly Once 语义在Flink中的实现(下) | 青训营笔记
|
SQL 运维 OLAP
二、【计算】流|批|OLAP一体 的Flink引擎(下) | 青训营笔记
二、【计算】流|批|OLAP一体 的Flink引擎(下) | 青训营笔记
二、【计算】流|批|OLAP一体 的Flink引擎(下) | 青训营笔记
|
存储 分布式计算 大数据
六、【计算】大数据Shuffle原理与实践(下) | 青训营笔记
六、【计算】大数据Shuffle原理与实践(下) | 青训营笔记
六、【计算】大数据Shuffle原理与实践(下) | 青训营笔记