mysql递归查询所有上下节点_可能是全网最深度的 Apache Kylin 查询剖析

19d55dc86e9dbdca842364563dbfaa07.png

自 6 月 6 日开始“征文赢首届 Kylin Data Summit 门票”活动以来,投稿的小伙伴络绎不绝,大家对 Kylin 的热爱与分享精神让我们燃到不行~

绝对重磅的第一篇投稿文章终于来啦!相信关注本号已久的粉丝对如何在 Kylin 里使用 SQL 进行查询已经再熟悉不过,但你知道在这亚秒级响应的背后,Kylin 是如何把对原始表的查询转换为对 Cube 的查询吗?来自蚂蚁金服的朱卫斌带来了 Kylin 查询深度剖析文为你揭晓答案。

一、概览

Apache Kylin 是 Hadoop 大数据平台上的一个开源 OLAP 引擎。它采用多维立方体(Cube)预计算技术,可以将某些场景下的大数据 SQL 查询速度提升到亚秒级别(相对于之前的分钟乃至小时级别的查询速度)。

由于其在 OLAP 领域出色的表现,在国内外积累了很多用户。我们知道,当用户输入一条 SQL 提交给 Kylin 进行查询时,该 SQL 是面向事实表和维度表的,而不是面向 Cube 的。当我看到这样的描述时,忍不住会想 Kylin 是怎么做到这一点的呢?相信很多使用 Kylin 的用户也会有相同的疑问,但遗憾的是,目前不管是出版的书籍还是网上能搜到的资料,都没有对这方面详细的介绍,所以就有了这篇文章。

本文将以一个典型的例子和大家一起从源码级别看看 Kylin 到底是怎么做到把对原始表的查询转换为对 Cube 的查询的。虽是源码级,但不会贴很多代码,尽量做到以流程图加描述的方式讲清楚这个过程。

本文以下方流程图开始部分的 sql text 为例剖析 Kylin 查询的详细过程,其中KYLIN_SALES 和 KYLIN_ACCOUNT 的表结构如下:

5a400f491191ae2bd01c56f20f7cebfb.png

0ab2195161342ea424e8881428149d28.png

流程图如下:

47a0c04db522f1222175daffd8b0969b.png

如上图,sql text 到物理执行计划主要分几个阶段:

1. sql text -> parsed SqlNode:使用 SqlParser 解析 SQL, 把 SQL 转换成为 AST(抽象语法树),用 SqlNode 来表示。

2. parsed SqlNode -> validated SqlNode:使用 SqlValidator 语法检查,根据 meta 的元数据信息进行语法验证,验证之后还是用 SqlNode 表示 AST 语法树。

3. validated SqlNode -> RelNode:使用 SqlToRelConverter 进行语义分析,根据 SqlNode 及元信息构建 RelNode 树,也就是最初版本的逻辑计划(Logical Plan)。

4. RelNode -> optimized RelNode:使用 HepPlanner 应用 Calcite 内置 rules 进行优化。

5. optimized RelNode -> OLAPRel:使用 VolcanoPlanner 应用 Kylin 自定义的 OLAP 相关 rules 到 HepPlanner 优化得到的 RelNode 上,得到 OLAPRel,OLAPRel 还是逻辑执行计划。OLAP rules 如下:

OLAPToEnumerableConverterRule: RelNode -> OLAPToEnumerableConverter

OLAPFilterRule: LogicalFilter -> OLAPFilterRel

OLAPProjectRule: LogicalProject -> OLAPProjectRel

OLAPAggregateRule: LogicalAggregate -> OLAPAggregateRel

OLAPJoinRule: LogicalJoin -> OLAPJoinRel/OLAPFilterRel

OLAPLimitRule: Sort -> OLAPLimitRel

OLAPSortRule: Sort -> OLAPSortRel

OLAPUnionRule: Union -> OLAPUnionRel

OLAPValuesRule: LogicalValues -> OLAPValuesRel

6. OLAPRel -> EnumerableRel:通过 OLAPToEnumerableConverter#implement 将 OLAPRel 转化为物理执行计划 EnumerableRel,这个过程中会递归调用各个 OLAPRel 节点的 implementOLAP、implementRewrite 等方法,也是在这一步中计算要使用哪个 Cube。

7. EnumerableRel -> java code:通过物理执行计划生成最终要执行的 java code,java code 包含读取数据、数据处理、计算结果。

上例中生成的 java code 见下文。

二、OLAPRel 生成物理执行计划

该过程主要封装在 OLAPToEnumerableConverter#implement 中,主要流程如下:

01e5413b844c4fb43a6e24028c7c6acd.png

implementOLAP、implementRewrite、implementEnumerable 为 OLAPRel 接口的方法,每个 OLAPRel 实现类都要有自己的实现,虽然各个实现不同,但可以进行一些归纳:

void implementOLAP(OLAPImplementor implementor):

  • 生成或修改自身一些成员,会影响自身 implementRewrite 的行为。
  • 修改 OLAPContext 的一些成员,会影响其他 OLAPRel 执行 implementOLAP 或 implementRewrite 方法来生成物理节点,并生成物理节点对应的 java code。

void implementRewrite(RewriteImplementor rewriter):

  • 会对算子、参数进行改写;这是把 SQL 表达的查原始表(事实表、维度表)改为查 Cube 的关键。
  • 虽然每个 OLAPRel 子类都实现了该方法,但不是所有的子类都会真正的去做重写。
  • rewrite 行为受自身或 OLAPContext 记录的上下文信息影响。

EnumerableRel implementEnumerable(List<EnumerableRel> inputs) :

  • 将自身转换成 EnumerableRel,即逻辑节点转为物理节点。
  • EnumerableRel#implement 方法返回的 Result 用来生成该物理节点对应的 java code。

我们以概览中的 SQL 来作为示例来对生成物理执行计划的过程进行分析。

后续章节更精彩:

三、递归调用各 OLAPRel#implementOLAP

四、选择 Realization

五、递归应用 implementRewrite

六、生成物理执行计划及 code gen

七、支持/不支持的场景

......

因全文含较多流程图与源码,戳此处下载本文完整版 PDF。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值