UDF原理与开发实践(1)-前置知识准备
HIVESQL解析流程
之前讲过,hivesql最终会被翻译成对应的MR程序最终执行(sparksql翻译到底层的RDDtask执行)等等,SQL只是一个抽象的语言。
- SQL的的执行流程
主要的流程:
1.词法/句法解析:有的是用的Antrl语言规则,有的用的是Calcite语法规则,通过该规则完成对sql语言的解析生成对应的抽象语法树(AST Tree)
ANTLR(Another Tool for Language Recognition),一个通过语法描述来自动构造自定义语言的识别器(recognizer),编译器(parser)和解释器(translator)的框架。。
- antlr是指可以根据输入自动生成语法树并可视化的显示出来的开源语法分析器,也就是不仅局限于解析sql,他可以分析任意定义好的语法。
- calciteApache Calcite 是一款开源SQL解析工具, 可以将各种SQL语句解析成抽象语法术AST(Abstract Syntax Tree), 之后通过操作AST就可以把SQL中所要表达的算法与关系体现在具体代码之中
2.语义解析:由于AST TREE结构相对比较复杂,不足以进行MR直接执行理解,因此还需要进一步对语法树进行翻译,通过对语法树结构进行遍历,将其语义化,转化成一个个queryblock,
queryblock:是SQL基本组成单位:包含输入、输出、计算过程,其实就是细化之后的原子查询,最简单的理解为一个独立的非嵌套查询
3.逻辑生成阶段:开始根据上面的queryblock,进行进一步拆解翻译为引擎可以理解的执行树-OperatorTree。
执行操作树:OperatorTree 包含具体的操作符,每个操作符在Map阶段或Reduce阶段执行对应的操作,比如如下的操作符:
- Join 对应Operator 执行join操作
- Fil filteroperator 执行过滤操作
- RS rduceoperator 执行reduce操作
- Sel selectoperator 执行select操作
4.逻辑优化:对具体的树结构进行合并裁剪优化操作
谓词下推
多路join
合并
查询改写
5.物理执行阶段:根据逻辑落到实际执行的task,具体就是具体的map或者reduce过程
6.物理执行计划优化:ABO/CBO优化
分区裁剪
列裁剪
Mapjoin
limit输出
....
JVM的内存结构
线程私有:程序计数器、虚拟机栈、本地方法区 线程共享:堆、方法区, 堆外内存(Java7的永久代或JDK8的元空间、代码缓存)
UDX介绍(以hive为例)
概念:UDF 即用户自定义函数,与引擎内置的UDF相比,是需要用户手动注册生效的函数,目前分为以下三类
UDF:自定义单值函数,输入与输出一一对应,一行输入,一行输出
UDTF:表值函数,一行输入,多行/多列输出
UDAF:聚合函数,多行输入,一行输出
UDJ:自定义join函数-odps
注册流程分析(HIVE为例):
- 用户通过对应引擎的API接口开发对应的UDF函数,然后进行注册;声明
- hive中通过Registry的相关函数进行函数注册
-- 临时函数 public static FunctionInfo registerTemporaryUDF( String functionName, Class<?> udfClass, FunctionResource... resources) { return SessionState.getRegistryForWrite().registerFunction( functionName, udfClass, resources); } --永久函数 public FunctionInfo registerGenericUDF(String functionName, Class<? extends GenericUDF> genericUDFClass, FunctionResource... resources) { validateClass(genericUDFClass, GenericUDF.class); FunctionInfo fI = new FunctionInfo(isNative, functionName, ReflectionUtils.newInstance(genericUDFClass, null), resources); addFunction(functionName, fI); return fI; }
该流程主要是:通过反射,拿到具体注册udf函数实体类的实例,然后调用addfucntion加入到registry中,然后将函数实例初始化生效。所以注册函数需要加上create tempory function 关键字声明。
说明:目前hiveudf有两个版本的接口或抽象类早期:org.apache.hadoop.hive.ql. exec.UDF/udaf/udtf ---目前已经不推荐使用现在:org.apache.hadoop.hive.ql.udf.generic.GenericUDF/UDTF/UDAF区别:早期处理的数据结构有限,都是简单的基本数据类型,后来的Generic可以更丰富,更强大。