可能是全网最深度的 Apache Kylin 查询剖析
自 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 的表结构如下:
流程图如下:
(点击图片查看大图)
如上图,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 中,主要流程如下:
(点击图片查看大图)
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,即可舒适地在 PC 端浏览本文。看懂全文的大佬快去评论区集合!有任何疑问,也欢迎在评论区与作者讨论~
往期案例与实践
Kylin 版本升级 | 从 v2.4.1 到 v2.6.1
有了 Kylin+Saiku,妈妈再也不用担心我的多维 OLAP 平台
OLAP 引擎这么多,麻袋财富为什么选择用 Kylin 做自助分析?
解读 Kylin 3.0.0 | 更敏捷、更高效的 OLAP 引擎
活动倒计时
首届 Kylin Data Summit 大会@上海将在 7 月 12 日正式拉开帷幕,届时 Gartner、微软、eBay 等企业的大咖将带你洞悉数据分析的未来趋势,包含针对增强分析以及云上分析的洞见,更有金融、制造、零售、互联网等行业的知名企业分享自己的成功经验。长按识别下方二维码了解活动详情!
点击“阅读原文”下载本文完整版PDF
点个“在看”给作者一朵小花花
有啥不懂的在评论区麻溜问