Flink SQL 是于2017年7月开始面向集团开放流计算服务的。虽然是一个很是年轻的产品,可是到双11期间已经支撑了数千个做业,在双11期间,Blink 做业的处理峰值达到了5+亿每秒,而其中仅 Flink SQL 做业的处理总峰值就达到了3亿/秒。Flink SQL 在这么短的时间内支撑了如此多的业务,与其稳定的内核、完善的功能、强大的生态是分不开的。html
本文会带着你们一块儿来揭开 Flink SQL 核心功能的面纱(API上咱们将尽量的和Flink社区保持一致,这样才可以更好的融入开源的生态,因此咱们将API叫作Flink SQL,而不是Blink SQL。事实上flink社区的SQL绝大部分是咱们阿里的工程师贡献的:3个 Flink Committer,10+ Contributor,贡献 80% 的SQL 功能,近200个 commit,近十万行的代码)。数据库
Blink 将 SQL 定位为其最核心的 API。为何是 SQL 而不是 DataStream API 呢?由于 SQL 具备如下几个优势:异步
咱们认为这 5 点对于用户的易用性是很是重要的,而以上 5 点倒是 DataStream API 所不具有的。因此 Blink 将 SQL 定位为最核心的 API,而不是 DataStream API。工具
关于流与批的统一是如今业界很是火热的一个话题,Flink SQL 的流与批统一总结起来就一句话:One Query, One Result。在不少场景,咱们既须要批处理,又须要流处理。好比,使用批处理一天跑一个全量,同时使用流处理来作实时的增量更新。在之前常常须要维护两套引擎,写两个 Job,两个 Job 之间还要维护逻辑的一致性,这增长了不少的工做量。若是使用 SQL 的话,咱们可让一份 SQL 代码既跑在批模式下,又跑在流模式下,这样用户只须要维护一份 SQL 代码,这是 One Query。而 One Result 是说,同一份 SQL 代码,在流模式下和批模式下跑出来的结果是同样的,也就是保证了流式 SQL 的语义正确性。性能
咱们注意到 SQL 是为传统批处理设计的,不是为流处理设计的。好比说传统 SQL处理的数据是有限的,并且SQL查询只返回一个结果并结束。可是流上的查询,处理的数据是无限的,不断产生结果且不会结束。因此说传统 SQL 标准中不少定义没法直接映射到流计算中。那么如何在流上定义 SQL 呢?这里须要引出 Flink SQL 的核心概念:流与表的二象性。学习
传统的 SQL 是定义在表上的,为了能在流上定义 SQL,咱们也须要有一个表的概念。这里就须要引入一个很是重要的概念:动态表(Dynamic Table)。所谓动态表,就是数据会随着时间变化的表,能够想象成就是数据库中一张被不断更新的表。咱们发现流与表有很是紧密的关系,流能够看作动态表,动态表能够看作流。咱们称之为流表二象性(duality)。优化
如上图所示,一个流能够看作对表的一系列更新操做(changelog),将流从头开始重放就能够构形成一个动态表。而动态表的每次更新操做都会记录下 changelog,经过抽取出动态表的 changelog 能够很轻松地获得原始的数据流(相似的思想也被应用于数据库同步中,如集团的DRC产品)。所以流能够转换成动态表,动态表又能转成流,他们之间的转换不会丢失任何信息,且保留了一致的 schema。流是动态表的另外一种表现形式,动态表也是流的另外一种表现形式,因此说流与表是一种二象性的关系。阿里云
上文说到动态表是流的另外一种表现形式,有了动态表后,咱们就能够在流上定义 SQL 了。流式 SQL 能够想象成连续查询(Continuous Query)。传统的查询是只运行一次 SQL,产生一个结果就结束了。连续查询会一直运行在那里,当每一个数据到来,都会持续增量地更新计算结果,从而产生另外一个动态表。而这个结果动态表(也就是流)会做为另外一个 SQL(连续查询)的输入接着计算,从而串起整个数据流图。spa
从 2016 年到 2017 年,Flink SQL 从无到有,迅速发展,解决多个 Stream SQL 领域的难点痛点,快速支持业务的需求。终于在今年的双11,Flink SQL 支撑了大量的双11业务,这与其丰富的上下游系统、完善的功能是离不开的,包括双流 JOIN,维表 JOIN,TopN,Window,多路输出等等。插件
Flink SQL 接入了集团内常见的十多种上下游系统,包括了11种结果表插件、5种源表插件、4种维表插件。只须要声明对接系统的类型,就能完成上下游系统的链接,将你从阿里云存储五花八门的 SDK 中解放出来。详见《Flink SQL 功能解密系列 —— 阿里云流计算/Blink支持的connectors》
双流 JOIN
双流 JOIN 功能是将两条流进行关联,用来补齐流上的字段。双流 JOIN 又分为无限流的双流 JOIN 和带窗口的双流 JOIN。
维表 JOIN
维表 JOIN 功能是流与表的关联,也是用来为数据流补齐字段,只是补齐的维度字段是在外部存储的维表中的。咱们为维表 JOIN 作了诸如 Async、cache、multi-join-merge 等优化,使得维表 JOIN 的性能很是优异。具体原理分析和最佳实践能够阅读《Flink SQL 功能解密系列 —— 维表 JOIN 与异步优化》
TopN
TopN 是统计报表和大屏很是常见的功能,主要用来实时计算排行榜。除了全局 TopN 功能外,咱们还提供了分组 TopN 的功能。流上的 TopN 有很是多的挑战。具体原理分析和实践推荐阅读《Flink SQL 功能解密系列 —— 流式 TopN 的挑战与实现》
Window
Flink SQL 简单易用的一大特点就是支持开箱即用的 Window 功能。支持滚动窗口(Tumble)、滑动窗口(Hop)、会话窗口(Session)以及传统数据库中的OVER窗口。具体使用方式能够阅读《Window 文档》
多路输入、多路输出
Flink SQL 利用分段优化支持了多路输出,而且多路输出的共享节点作到了资源的复用,使得不会计算屡次。基于多路输入、多路输出的功能,能够将 Flink SQL 做为一个很是简单易用的画数据流的工具,能够很容易地构造出一个有流合并、流拆分的复杂 DAG 做业。
MiniBatch 优化
除此以外,咱们还在 SQL 上作了不少的优化。其中 MiniBatch 就是核心优化之一。对于有状态的算子来讲,每一个进入算子的元素都须要对状态作序列化/反序列化的操做,频繁的状态序列化/反序列化操做占了性能开销的大半。MiniBatch 的核心思想是,对进入算子的元素进行攒批,一批数据只须要对状态序列化/反序列化一次便可,极大地提高了性能。详细的原理实现推荐阅读《Flink SQL 功能解密系列 —— 解决热点问题的大杀器 MiniBatch》
Retraction 撤回机制
撤回机制是 Flink SQL 中一个很是重要的基石,它解决了 early-fire 致使的结果正确性问题(全部的 GroupBy 都是 early-fire 的)。而利用好撤回机制有时候可以很巧妙地帮助业务解决一些特殊需求。详细的业务应用分析推荐阅读《Flink SQL 功能解密系列 —— 流计算“撤回(Retraction)”案例分析》