想提升查询性能?openLooKeng 新下推框架助您一臂之力
openLooKeng 执行计划优化简介
在讲述下推框架之前,我们先来简单介绍一下 openLooKeng 执行计划优化的大致流程。
如上图所示,接收到用户 SQL 语句之后,SQL 被转换成一个 Abstract syntax tree (AST)树。AST 树再被转换成逻辑执行计划树。然后,也就是执行计划优化过程中最重要的一步,使用规则(Rule)或者优化器(Optimizers)进行执行计划优化,每一个 PlanOptimizer 可以操作一个子执行计划树,PlanOptimizer 基于统计或者经验,用一个更优的子执行计划替换当前的子树,达到优化的目的。PlanOptimizers 通常是长期的经验累积得出来的一些优化规则,比如谓词下推、join reorder 等等。PlanOptimizers 可以存储一些物理执行信息在 ConnectorHandle 中。新下推框架则工作在这一层。
得到最优的执行计划之后,逻辑执行计划被转换成物理执行计划,然后被分片,分割成按照 stage 执行的一个个子树,最终调度到 worker 上执行。
PrestoSql 下推方案介绍
最初,openLooKeng 是从 PrestoSql 演进而来,在其基础上增加了很多功能特性,以及大量的性能优化。在讲述 openLooKeng 的新下推框架之前,先大概介绍其原下推方案。
根据社区的讨论,PrestoSql 原下推框架有一些目标:
1)使用现有的 Rule 或 Optimizer 的框架,而且不是使用基于 visitor 模式的 PlanOptimizers 来实现下推,同时能够让 connector 提供转换 rules 来实现下推;
2)并不是建立一个原生的机制来支持所有操作的下推。
先来看看 prestoSql 的执行过程:
1)首先,引入一些列的下推规则,每一个规则负责下推相应的操作到 TableScan 操作中,比如 PushFilterIntoConnector, PushProjectionIntoConnector, PushAggregationIntoConnector 等等;
2)上述的这些 rules 通过指定的 metadata 调用与 connectors 交互,如果 connector 支持这个操作下推,操作则被下推到 TableScan 操作,同时在 connectorTableHadle 中记录相关信息。
下面以 PushFilterIntoConnector 为例说明。
在上述的例子中,假设 filter 中有两个过滤条件,一个是 like,一个是 f 函数,其中 connector 能处理 like 表达式。
PushFilterIntoConnector 会调用 Metadata.pushFilter,实际上是调用 connector 的 pushFilter 函数,这个函数会返回一个新的 tableHandle,新的 tableHandle 中记录了 like 表达式的相关信息,同时返回一个 remaining filter,即 connector 不能处理的表达式。最终,PushFilterIntoConnector 就把原来的执行计划(上图中第一个框)转换成一个新的执行计划(上图中最后一个框)。
上述的基于 Rule 的下推方案存在以下的几个问题:
1)不能 JoinNode,WindowNode 等 Nodes 的下推,特别是 join 的情况,join node 不仅仅需要 visit 当前的 join node,还需要 visit 他的左右节点,同时,还需要保存 join 的上下文信息,基于 rule 的下推方案难以处理这种情况;
2)下推逻辑复杂,下推上下文信息无法保存,对于 Join 的情况,join 的下推信息不知道存储在哪。
3) 基于上述原因,当前的下推方案不能把 sql 语句下推到数据源操作中,这样对于那些执行速度相当快的数据源就不能充分发挥数据源本身的能力,所以引入了新的下推框架。
openLooKeng 新的下推框架
思想
openLooKeng 新下推框架的主要思想是把执行计划子树暴露给 connector,让 connector 提供 PlanOptimizers(基于 visitor 模式的)给执行优化引擎,这样可以让 connector 引入任意的优化。
为了防止一个 connector 的 PlanOptimizers 修改其他 connector 的执行计划子树,openLooKeng 对于暴露给 Connector 的 PlanNode 做了两个限制:
1)暴露出来的 PlanNodes 须移动到 presto-spi 模块;
2)仅仅暴露属于 connector 的子执行计划树给相应的 connector。如下图所示,左子树只会暴露给 Hive Connector,右子树只会暴露给 Mysql Connector。然后会应用他们各自的 PlanOptimizers。
实现
openLooKeng 的下推框架如上图所示,新下推框架的工作原理很简单,主要分为两步:
1)Connector 在启动的时候会告诉执行优化引擎其提供的 ConnectorPlanOptimizer,如下图的 HiveFpuPushdownOptimizer,其需要实现上图的 optimize 接口,optimize 函数以子执行计划为入口,返回优化后的执行计划;
2)在执行优化引擎中引入 ApplyConnectorOptimization 优化器,
该 Optimizer 会把根据子执行计划所在的 connector,调用其 connectorPlanOptimizer。如下图所示,经过 HiveFpuPushdownOptimizer 优化之后,Aggregation 和 Filter 操作都下推到了数据源中。
修改
新框架特性 PR 链接为
https://gitee.com/openlookeng/hetu-core/pulls/633,
主要做了如下修改:
移动 PlanNodes 到 presto-spi 模块
修改 PlanNode 和 Assignments 中的 Expression 为 RowExpression(下一节描述)
添加 TranslateExpressions 和 ApplyConnectorOptimization Optimizer
修改已经存在的 Rules 和 Optimizers
为 connector 添加 ConnectorPlanOptimizer
Expression-to-RowExpression
在数据库或者查询系统中,为了更好的隔离,AST 树和 IR 树是隔离,他们使用的数据结构也不一样,这也就是 presto 社区讨论的分离 AST(Node)和 IR(PlanNode)。具体就是指把 AST 树种的 Expression 转换成 PlanNode 中的 RowExpression。当前 AST 和 PlanNode 在混用 Expression,不能做到很好的隔离。rker 上执行。
当前一个执行计划的生命周期如下:
building AST
building raw plan
plan optimization
plan sanity check
plan cost computation
building subplans
distributing subplan (over the wire)
compiling subplan locally
当前,Expression 到 RowExpression 的转换发生在第 8 步。我们把转换这个操作移到了第 3 步。之所以没有把没有把转换移到第二步,是因为涉及的面太广了,修改量太大了。
Example 演示
首先,在演示系统中配置了三个 catalog,他们都指向同一个数据源,不过下推的设置不一样,mysql2 不下推,mysql1 部分下推(join 不下推),mysql 全下推。
不下推的情况
部分下推的情况,在这个例子中,filter 下推了
全部下推情况
如何贡献
下面简单介绍一下开发者如何适配新的下推框架,即在新增的 connector 中,如何添加 connectorPlanOptimizer。主要步骤如下:
第一:在 XXXConnector 中复写下面的函数
第二:实现 XXXPlanOptimizerProvider
第三:在 XXXConnector 中实现 PlanOptimizer
第四:实现 PlanOptimizer 里面的 optimize 函数,主要是实现一个 visitor 去 visit 执行计划树
第五:实现 Visitor,用来生成下推的语句,同时修改执行计划树
第六:实现 XXXQueryGenerator,在 XXXQueryGenerator 中实现一个 visitor 用来把下推的信息记录到 XXXQueryGeneratorContext,如果存在节点可以下推,则生成对应的 sql
详细的实现可以参考 openLooKeng 的 baseJdbc 的实现,实现了 JDBC 数据源的下推。
以上便是 openLooKeng 开发工程师罗旦带来的分享。
直播视频回顾:https://www.bilibili.com/video/BV1of4y1p7sc
活动官网:https://summer.iscas.ac.cn/
学生指南:https://summer.iscas.ac.cn/help/student/
任务详情:https://summer.iscas.ac.cn/#/org/orgdetail/openlookeng
openLooKeng 是一款开源的高性能数据虚拟化引擎,提供统一 SQL 接口,具备跨数据源/数据中心分析能力,为大数据用户提供极简的数据分析体验。
openLooKeng 开源社区官方网站: https://openlookeng.io/zh-cn/
openLooKeng 代码仓地址: http://gitee.com/openlookeng
版权声明: 本文为 InfoQ 作者【openLooKeng】的原创文章。
原文链接:【http://xie.infoq.cn/article/9a6b5f22acda05a3e1ae30a40】。文章转载请联系作者。
评论