山大软工实践hive(12)-逻辑优化过程中的六种基础接口的作用与关系的梳理

2021SC@SDUSC

山大软工实践hive(12)-逻辑优化过程中的六种基础接口的作用与关系的梳理

目的

这一次梳理一下各大接口之间的关系,正好它们都在 package org.apache.hadoop.hive.ql.lib;
在这里插入图片描述
共六种,当然实际结构的交互不止这些接口

Node

在这里插入图片描述
它是DAG算子结构的基础,关系是算子继承Operator,Operator实现Node
它要求实现两个方法以达到:能够遍历出DAG的结构,以及识别每个Node是什么种类
它是数据结构的骨架

它的注释上,更倾向于描述它在逻辑优化上的用处:它需要实现的方法让Dispatcher和Walker调用

另外,在了解过程中,有一个不像算子的东西继承了Node,它是ExprNodeDesc,在优化器里表现为predicate的类型,可以认为是一种储存语句信息的类型
在这里插入图片描述
关于它在类机构上的位置,比如FIL算子类上,FilterDesc里就会储存ExprNodeDesc类型的变量
在这里插入图片描述
另外这些Desc有统一的接口
在这里插入图片描述
所以这一部分可以认为是,不同的算子实现不同的Operator,Operator的不同之处体现于它的泛型,这些Desc会储存ExprNodeDesc的变量,它关于着算子对应的语句(比如where id=3)

Rule

在这里插入图片描述
它被用于dispatch过程
它必须要实现两个方法,cost用于计算开销,getName没什么用,或许能被用于Debug

实现这接口的类很少
在这里插入图片描述
而我接触过的优化器用的都是RuleRegExp
在这里插入图片描述
而RuleRegExp是优化器transform方法里很早就会用到的类型,它的规则明显地区分了各优化器
关于它的规则长啥样:

  1. 输入Name如R1对应它的名字,也是getName()返回的东西
  2. 输入正则表达式一样的规则如“FIL%”,“TS%.*RS%”来匹配不同的算子结构,只有DAG,准确的说是,dispatch时传入的栈中有能匹配上的结构,其中%只是每个算子后必加的符号,除了分割算子没有其他意义
  3. cost方法算的是匹配的字符串长度,而不是算子链长度,所以怀疑算子名字的长度本身带有开销的意味

下面是找到的带有正则的规则
在这里插入图片描述

GraphWalker

在这里插入图片描述
添加完规则后,会先声明Dispatcher,但下一步运行的是Walker的方法
接口方法只有startWalking:用于启动对DAG的walk

但是实际上,所有Walker都继承DefaultGraphWalker,更多的实现在这个类里
在这里插入图片描述
它有默认的一系列方法:

  1. 初始化:传入的参数有Dispatcher,它需要保存这个,才能在walk到一个正确的点后进行dispatch;然后初始化自己的栈和队列,栈是储存walk过程中的路径,并且传入Dispatcher,队列记录了被dispatch节点的先后顺序。另外还有retMap,用于储存各个节点的dispatch后的信息
  2. startWalking:启动walk,从传入的头节点集合一个一个拿出来启动walk。。。
  3. walk:怎样对DAG上的节点dispatch,默认的方法是所有子节点先被dispatch,栈存的是从头结点到这个字节点的一条路径;其他的Walker可能会有不同的策略如优先父节点,并且栈存的节点的次序也可能不同。这个方法是最有可能改动的
  4. dispatch与dispatchAndReturn:总之就是开始调用dispatcher的方法了
  5. 其他:略

Dispatcher

在这里插入图片描述
需要实现dispatch方法:它用于判断一个算子能不能被优化,如何被优化

用DefaultRuleDispatcher举例
在这里插入图片描述
它的流程是:
对一个算子,找到它匹配的所有规则(Rule)里的cost最小规则,如果不存在,则用默认的NodeProcessor(优化器输入),反之则用规则对应的优化器(储存在一个map里),对node进行process

另外,翻了一些其他的Dispatcher,他们的dispatch方法很不相同

NodeProcessor

在这里插入图片描述
process:用于执行的算子的逻辑优化,也是逻辑优化过程中对语句产生真正的修改的地方
关于怎么使用,会在开始时记录一个 map<Rule,Processor>,每种Rule对应一种Processor,并且在后面初始化dispatcher时还会传入一个默认的Processor

这个类的实现很多,各种内部类,各种单独的子方法,甚至有的会在方法里又进行一次walk,再起进行一遍优化流程
目前我看的两个优化器里,相同的地方是:都会从算子拿出旧的predicate,然后对其修改(也可能不改),然后新的predicate放回去,并记录在retMap里

下面是一个processor的实现,它是PointLookUpOptimizer的内部类,可以看见它对predicate的修改
在这里插入图片描述
这个processor的子方法,它又walk了,并且规则对应另一个processor
在这里插入图片描述
另一个processor,也是这个类的内部类,很长,是真正对语句修改的地方
在这里插入图片描述

NodeProcessorCtx

在这里插入图片描述
这个是在找lib包时才发现的,之前对这个没有印象,甚至可能完全没见过
另外,这上面有一大堆注释,不过是和什么许可证有关
感觉也是个存各种信息、变量的地方,之前看优化器有查到过一个相关的类,注释是处理常量传播时的上下文在这里插入图片描述

但凡包含Context(ctx)的类,我认为是存的与某流程相关的环境:各种变量,boolean,阈值,等等

总结

这一次梳理了各个接口的关系,也变相地梳理了优化器的流程

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值