Flink SQL w/ Blink Planner执行流程解析(上篇)

Foreword

大数据领域SQL化的风潮方兴未艾(所谓"Everybody knows SQL"),Flink自然也不能“免俗”。Flink SQL是Flink系统内部最高级别的API,也是流批一体思想的集大成者。用户可以通过简单明了的SQL语句像查表一样执行流任务或批任务,屏蔽了底层DataStream/DataSet API的复杂细节,降低了使用门槛。

那么,一条Flink SQL语句是如何转化成可执行的任务的呢?本文以最新的Flink 1.11版本为蓝本,分上下两篇详细梳理流程。在此之前,先简要介绍Apache Calcite与Blink Planner。

Prerequisite: Apache Calcite & Workflow

不同于Spark专门打造Catalyst作为其SQL层核心的骚操作,Flink没有重复造轮子,而是务实地直接利用了通用的SQL解析与优化引擎——Apache Calcite。Calcite在Hive、Drill、Pheonix、Kylin诸框架中都已经有了非常成熟的应用,Flink选择它也是情理之中。

下图示出Calcite在整个Flink Table & SQL体系中的作用。

Flink SQL w/ Blink Planner执行流程解析(上篇)_第1张图片
image

可见,Calcite在此体系内需要负责以下任务:

  • 解析(parsing)——将SQL语句转化为抽象语法树(AST),即SqlNode树。
  • 验证(validation)——根据Catalog中的元数据进行语法检查。
  • 逻辑计划(logical planning)——根据AST和元数据构造出逻辑计划,即RelNode树。
  • 逻辑计划优化(logical plan optimization)——按照预定义的优化规则RelOptRule优化逻辑计划。Calcite中的优化器RelOptPlanner有两种,一是基于规则优化(RBO)的HepPlanner,二是基于代价优化(CBO)的VolcanoPlanner。
  • 物理计划(physical planning)——将优化的逻辑计划翻译成对应执行逻辑的物理计划。

前4个阶段其实就是Calcite的标准工作流,同时这5个阶段也基本上涵盖了Flink SQL执行流程的主体部分。Table API相对于SQL只是在解析、验证方面有些不同(解析的不是SQL语句而是算子树,再用Calcite RelBuilder生成逻辑计划)。而在物理计划之后,还需要通过代码生成(code generation)最终转化为能够直接执行的DataStream/DataSet API程序。下面分析Flink SQL的执行步骤时,就以上面的5 + 1 = 6个阶段为准。

本文作为上篇,先讲解比较简单的解析、验证和逻辑计划,下篇再讲解比较复杂的逻辑计划优化、物理计划和代码生成。

关于Calcite细节的讲解有珠玉在前,看官可直接参考以下几篇文章,本文不再班门弄斧了。

  • 《Apache Calcite: A Foundational Framework for Optimized Query Processing Over Heterogeneous Data Sources》 from SIGMOD 2018 by E.Begoli et al.
  • 《Apache Calcite处理流程详解(一)》 from matt33.com
  • 《Apache Calcite优化器详解(二)》 from matt33.com

Prerequisite: Blink Planner

Flink Table/SQL体系中的Planner(即查询处理器)是沟通Flink与Calcite的桥梁,为Table/SQL API提供完整的解析、优化和执行环境。Blink Planner从1.9版本开始合并到Flink主干,并从1.11版本开始成为默认Planner,而原有的Old Planner将会逐渐退役。

Blink Planner真正地践行了流批一体的处理方式。它根据流处理作业和批处理作业的不同,分别提供了StreamPlanner和BatchPlanner两种实现。这两种Planner的底层共享了基类PlannerBase的很多源码,且作业最终都会翻译成基于DataStream Transformation API的执行逻辑(即将批处理视为流处理的特殊情况)。通过如下类图即可看出一二。

你可能感兴趣的:(java,sql,flink,hive,大数据)