腾讯基于 Flink SQL 的功能扩展与深度优化实践
Flink SQL 现状
窗口功能的扩展
回撤流的优化
未来的规划
Tips:点击文末「阅读原文」即可回顾作者原版分享视频~
一、背景及现状
■ Jar 模式
Jar 模式基于 DataStream/DataSet API 开发,主要针对的是底层的开发人员。
优点:
功能灵活多变,因为它底层的 DataStream/DataSet API 是 Flink 的原生 API,你可以用它们开发任何你想要的算子功能或者 DAG 图;
性能优化方便,可以非常有针对性的去优化每一个算子的性能。
缺点:
依赖更新繁琐,无论扩展作业逻辑或是 Flink 版本的升级,都要去更新作业的代码以及依赖版本;
学习门槛较高。
■ 画布模式
所谓的画布模式,一般来讲会提供一个可视化的拖拉拽界面,让用户通过界面化的方式去进行拖拉拽操作,以完成 Flink 作业的编辑。它面向一些小白用户。
优点:
操作便捷,画布上可以很方便地定义 Flink 的作业所包含的各种算子;
功能较全,它基于 Table API 开发,功能覆盖比较完整;
易于理解,DAG 图比较直观,用户能够非常容易的去理解整个作业的运行流程。
缺点:
配置复杂:每一个算子都需要去逐个的去配置,如果整个 DAG 图非常复杂,相应的配置工作也会非常大;
逻辑重用困难:如果作业非常的多,不同的作业之间想去共享 DAG 逻辑的话非常困难。
优点:
清晰简洁,易于理解和阅读;
与计算引擎解耦,SQL 与计算引擎及其版本是解耦的,在不同的计算引擎之间迁移业务逻辑不需要或极少需要去更改整段 SQL。同时,如果想升级 Flink 版本,也是不需要去更改 SQL;
逻辑重用方便,可以通过 create view 的方式去重用我们的 SQL 逻辑。
缺点:
语法不统一,比如说流与维表 Join,Flink 1.9 之前使用 Lateral Table Join 语法,但是在 1.9 之后,更改成了 PERIOD FOR SYSTEM_TIME 语法,这种语法遵循了 SQL ANSI 2011 标准。语法的变动使得用户有一定的学习成本;
功能覆盖不全:Flink SQL 这个模块存在的时间不是很长,导致它的功能的一个覆盖不是很全。
性能调优困难:一段 SQL 的执行效率主要由几个部分来决定,一个就是 SQL 本身所表达的业务逻辑;另一部分是翻译 SQL 所产生的执行计划的一个优化;第三部分的话,在产生最优的逻辑执行计划之后,翻译成本地的 native code 的时候方案也决定了 SQL 的执行效率;对于用户来讲的,他们所能优化的内容可能只局限于 SQL 所表达的业务逻辑。
问题定位困难:SQL 是一个完整的执行流程,如果我们发现某些数据不对,想针对性地去排查到底是哪个算子出了问题,是比较的困难的。一般来讲,我们想定位 Flink SQL 的问题,只能先不断的精简我们的整个 SQL 逻辑,然后不断地去尝试输出,这个成本是非常高的。腾讯实时计算平台后期会针对这个问题,增加 trace 日志和 metrics 信息,输出到产品侧以帮助用户定位 Flink SQL 使用上的问题。
■ 扩展语法
定义了 window table-valued function 语法,以帮助用户实现基于窗口的流 Join 和交并差操作。另外,实现了自己的流与维表 Join 的语法。
■ 新增功能
新增的一些功能,包括两个新的 Window 的类型,Incremental Window(增量窗口)和 Ehanced Tumble Window(增强窗口)。实现了 Eventtime Field 与 Table Source 的解耦,很多时候 Eventtime Field 并不能通过 Table Source 字段定义出来,比如 Table Source 是一个子查询或者某个时间字段是由函数转换得出,想要用这些中间生成的时间字段作为 Eventtime Field 目前是做不到的,我们目前的方案是,让用户可以选择物理表中任意的时间字段来定义 Window 的时间属性并输出 WaterMark。
■ 性能调优
回撤流优化;
内联 UDF,如果相同的 UDF 既出现在 LogicalProject 中,又出现在 Where 条件中,那么 UDF 会进行多次调用。将逻辑执行计划中重复调用的 UDF 提取出来,将该 UDF 的执行结果进行缓存,避免多次调用;
二、 窗口功能扩展
■ 1.1 先 Join 再开窗
状态无法清理:因为 Join 在开窗之前,Join 里面并没有带 Window 的信息,即使下游的 Window 触发并完成计算,上游两条流的 Join 状态也无法被清理掉,顶多只能使用基于 TTL 的方式去清理。
语义无法满足需求:原始的需求是想在两条流中基于相同的时间窗口去把数据进行切片后再 Join,但是当前方案并不能满足这样的需求,因为它先做 Join,使用 Join 后的数据再进行开窗,这种方式不能确保两条流中参与 Join 的数据是基于同一窗口的。
■ 1.2 Interval Join
想象一下现有两条速率不一致的流,以 low 和 upper 两条边界来限定左流可以 Join 的右流的数据范围,在如此死板的范围约束下,右流总会存在一些有效数据落在时间窗口 [left + low, left + upper] 之外,导致计算不够准确。因此,最好还是按照窗口对齐的方式来划分时间窗口,让两条流中 Eventtime 相同的数据落在相同的时间窗口。
■ 1.3 Windowing Table-Valued Function
在单流上面,可以像现有的 Group Window 语法一样去划分出一个时间窗口。写法如上图,Window 信息全部放到 From 子句中,然后再进行 Group By。这种写法应该更符合大众对于时间窗口的理解,比当前 Flink SQL 中的 Group Window 的写法更加直观一点。我们在翻译单流上的 Windowing Table-Valued Function 语法时做了一个讨巧,即在实现这段 SQL 的物理翻译时,并没有去翻译成具体的 DataStream API,而是将其逻辑执行计划直接变换到现在的 Group Window 的逻辑执行计划,也就是说共用了底层物理执行计划的代码,只是做了一个逻辑执行计划的等价。
另外,可以对 Window 里面的数据做一些 Sort 或者 TopN 的一些输出,因为 Windowing Table-Valued Function 语法已经提前把数据划分进了一个个确定的窗口。如上图所示,首先在 From 子句里面把窗口划分好,然后 Order By 和 Limit 紧接其后,直接表达了排序和 TopN 语义。
在双流上面,可以满足“在两条流上针对某个时间窗口做 Join 操作或者交并差操作”的原始需求。语法如上图,首先把两个窗口的 Window Table 构造好,然后利用 Join 关键字进行 Join 操作即可;交并差操作也一样,与传统数据库 SQL 的交并差操作无二。
■ 1.4 实现细节
1.4.1 窗口的传播
1.4.2 时间属性字段
SELECT * FROM TABLE(TUMBLE(TABLE <data>, DESCRIPTOR(<timecol>), <size> [, <offset>]))
1.4.3 时间水印
1.4.4 使用约束
■ 2.1 Incremental Window
2.1.1 多次触发
2.1.2 Lazy Trigger
■ 2.2 Enhanced Tumble Window
三、回撤流优化
■ 2.1 什么时候产生回撤流
Aggregate Without Window(不带 Window 的聚合场景)
Rank
Over Window
Left/Right/Full Outer Join
(图片来源于云栖社区)
■ 2.2 如何处理回撤消息
■ 2.3 相关优化
2.3.1 中间节点的优化
第一个场景是一个嵌套 AGG 的场景(例如两次 Count操作),在第一层 Group By 尝试将更新结果发送到下游时候会先做一个 Cache,从而减少向下游发送数据频率。当达到了 Cache 的触发条件时,再把更新结果发送到下游。
第二个场景是 Outer Join,前面提到,Outer Join 产生回撤消息是因为左右两边数据的速率不匹配。以 Left Outer Join 为例,可以把左流的数据进行 Cache。左流数据到达时会去右流的状态里面查找,如果能找到可以与之 Join的数据则不作缓存;如果找不到相应数据,则对这条 Key 的数据先做缓存,当到达某些触发条件时,再去右流状态中查找一次,如果仍然找不到相应数据,再去向下游发送一条包含 Null 值的 Join 数据,之后右流相应数据到达就会将 Cache 中该 Key 对应的缓存清空,并向下游发送一条回撤消息。
2.3.2 Sink 节点的优化
四、未来规划
-
Cost-Based Optimization :现在 Flink SQL 的逻辑执行计划的优化还是基于RBO(Rule Based Optimization)的方式。我们团队想基于 CBO 所做一些事,主要的工作还是统计信息的收集。统计信息不仅仅来自 Flink SQL 本身,可能还会来自公司内其他产品,例如元数据,不同 Key 所对应的数据分布,或者其他数据分析结果。通过跟公司内其他产品打通,拿到最准的统计数据,产生最优的执行计划。
-
More New Features(CEP Syntax etc.) : 基于 Flink SQL 定义一些 CEP 的语法,以满足用户关于 CEP 的一些需求。
-
Continuous Performance Optimization(Join Operator etc.) : 我们团队在做的不仅仅是执行计划层的优化,也在做 Join Operator 或者说数据 Shuffle 的一些细粒度的优化。
-
Easier To Debug : 最后是关于 Flink SQL任务的调试和定位。 目前 Flink SQL在这方面是比较欠缺的,特别是线上关于数据对不齐的问题,排查起来非常的棘手。 我们目前的思路是通过配置的方式,让 SQL 在执行的过程中吐出一些 Trace 信息或者一些 Metrics 信息,然后发送到其他平台。 通过这些 Trace 信息和 Metric 信息,帮助用户定位出问题的算子。
▼ 关注「Flink 中文社区」,获取更多技术干货 ▼
本文分享自微信公众号 - Flink 中文社区(gh_5efd76d10a8d)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
项目实践 | 行人跟踪与摔倒检测报警(文末获取完整源码)
1、简介 本项目的目的是为了给大家提供跟多的实战思路,抛砖引玉为大家提供一个案例,也希望读者可以根据该方法实现更多的思想与想法,也希望读者可以改进该项目种提到的方法,比如改进其中的行人检测器、跟踪方法、行为识别算法等等。 本项目主要检测识别的行为有7类:Standing, Walking, Sitting, Lying Down, Stand up, Sit down, Fall Down。 2、项目方法简介 本文涉及的方法与算法包括:YOLO V3 Tiny、Deepsort、ST-GCN方法,其中YOLO V3 Tiny用于行人检测、DeepSort用于跟踪、而ST-GCN则是用于行为检测。 这里由于YOLO与DeepSort大家都已经比较了解,因此这里只简单说明一下ST-GCN 的流程,这里ST-GCN 的方法结构图如下: 给出一个动作视频的骨架序列信息,首先构造出表示该骨架序列信息的图结构,ST-GCN的输入就是图节点上的关节坐标向量,然后是一系列时空图卷积操作来提取高层的特征,最后用SofMax分类器得到对应的动作分类。整个过程实现了端到端的训练。 GCN 帮助我们学习了到空...
- 下一篇
MySQL中怎样快速找出超长索引
大家好,我是知数堂SQL 优化班老师 网名:骑龟的兔子 需求: 想要查找哪些索引太长了,这个SQL在5.7下跑的特别慢,8.0则挺快的,帮看下有啥优化方案没 具体SQL 和执行计划如下: SELECT c.TABLE_SCHEMA AS DB, c .TABLE_NAME AS TBL, c.COLUMN_NAME AS COL, c.CHARACTER_OCTET_LENGTH AS COL_LEN_BYTES, s.INDEX_NAME, s.SUB_PART * CHARACTER_OCTET_LENGTH/CHARACTER_MAXIMUM_LENGTH AS SUB_PART_LENFROM information_schema.COLUMNS c INNER JOIN information_schema.STATISTICS s USING(TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME)INNER JOIN information_schema.TABLES t USING(TABLE_SCHEMA, TABLE_NAME) WHERE c....
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS8编译安装MySQL8.0.19
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS6,CentOS7官方镜像安装Oracle11G
- CentOS关闭SELinux安全模块
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池