SQL转化为MapReduce的过程
转载:http://www.cnblogs.com/yaojingang/p/5446310.html
在了解了MapReduce实现SQL基本操作之后,我们来看看Hive是如何将SQL转化为MapReduce任务的,整个编译过程分为六个阶段:
- Antlr定义SQL的语法规则,完成SQL词法,语法解析,将SQL转化为抽象语法树AST Tree
- 遍历AST Tree,抽象出查询的基本组成单元QueryBlock
- 遍历QueryBlock,翻译为执行操作树OperatorTree
- 逻辑层优化器进行OperatorTree变换,合并不必要的ReduceSinkOperator,减少shuffle数据量
- 遍历OperatorTree,翻译为MapReduce任务
- 物理层优化器进行MapReduce任务的变换,生成最终的执行计划
下面分别对这六个阶段进行介绍
Phase1 - SQL词法,语法解析
Antlr
Hive使用Antlr实现SQL的词法和语法解析。Antlr是一种语言识别的工具,可以用来构造领域语言。
这里不详细介绍Antlr,只需要了解使用Antlr构造特定的语言只需要编写一个语法文件,定义词法和语法替换规则即可,Antlr完成了词法分析、语法分析、语义分析、中间代码生成的过程。
Hive中语法规则的定义文件在0.10版本以前是Hive.g一个文件,随着语法规则越来越复杂,由语法规则生成的Java解析类可能超过Java类文 件的最大上限,0.11版本将Hive.g拆成了5个文件,词法规则HiveLexer.g和语法规则的4个文件 SelectClauseParser.g,FromClauseParser.g,IdentifiersParser.g,HiveParser.g。
抽象语法树AST Tree
经过词法和语法解析后,如果需要对表达式做进一步的处理,使用 Antlr 的抽象语法树语法Abstract Syntax Tree,在语法分析的同时将输入语句转换成抽象语法树,后续在遍历语法树时完成进一步的处理。
下面的一段语法是Hive SQL中SelectStatement的语法规则,从中可以看出,SelectStatement包含select, from, where, groupby, having, orderby等子句。
(在下面的语法规则中,箭头表示对于原语句的改写,改写后会加入一些特殊词标示特定语法,比如TOK_QUERY标示一个查询块)
Phase2 - SQL基本组成单元QueryBlock
AST Tree仍然非常复杂,不够结构化,不方便直接翻译为MapReduce程序,AST Tree转化为QueryBlock就是将SQL进一部抽象和结构化。
QueryBlock
QueryBlock是一条SQL最基本的组成单元,包括三个部分:输入源,计算过程,输出。简单来讲一个QueryBlock就是一个子查询。
下图为Hive中QueryBlock相关对象的类图,解释图中几个重要的属性
- QB#aliasToSubq(表示QB类的aliasToSubq属性)保存子查询的QB对象,aliasToSubq key值是子查询的别名
- QB#qbp 即QBParseInfo保存一个基本SQL单元中的给个操作部分的AST Tree结构,QBParseInfo#nameToDest这个HashMap保存查询单元的输出,key的形式是inclause-i(由于Hive 支持Multi Insert语句,所以可能有多个输出),value是对应的ASTNode节点,即TOK_DESTINATION节点。类QBParseInfo其余 HashMap属性分别保存输出和各个操作的ASTNode节点的对应关系。
- QBParseInfo#JoinExpr保存TOK_JOIN节点。QB#QBJoinTree是对Join语法树的结构化。
- QB#qbm保存每个输入表的元信息,比如表在HDFS上的路径,保存表数据的文件格式等。
- QBExpr这个对象是为了表示Union操作。
AST Tree生成QueryBlock
AST Tree生成QueryBlock的过程是一个递归的过程,先序遍历AST Tree,遇到不同的Token节点,保存到相应的属性中,主要包含以下几个过程
- TOK_QUERY => 创建QB对象,循环递归子节点
- TOK_FROM => 将表名语法部分保存到QB对象的
TOK_INSERT => 循环递归子节点
TOK_DESTINATION => 将输出目标的语法部分保存在QBParseInfo对象的nameToDest属性中
TOK_SELECT => 分别将查询表达式的语法部分保存在
destToAggregationExprs、TOK_WHERE => 将Where部分的语法保存在QBParseInfo对象的destToWhereExpr属性中
最终样例SQL生成两个QB对象,QB对象的关系如下,QB1是外层查询,QB2是子查询
QB1 \ QB2
Phase3 - 逻辑操作符Operator
Operator
Hive最终生成的MapReduce任务,Map阶段和Reduce阶段均由OperatorTree组成。逻辑操作符,就是在Map阶段或者Reduce阶段完成单一特定的操作。
基本的操作符包括TableScanOperator,SelectOperator,FilterOperator,JoinOperator,GroupByOperator,ReduceSinkOperator
从名字就能猜出各个操作符完成的功能,TableScanOperator从MapReduce框架的Map接口原始输入表的数据,控制扫描表的数据行数,标记是从原表中取数据。JoinOperator完成Join操作。FilterOperator完成过滤操作
ReduceSinkOperator将Map端的字段组合序列化为Reduce Key/value, Partition Key,只可能出现在Map阶段,同时也标志着Hive生成的MapReduce程序中Map阶段的结束。
Phase4 - 逻辑层优化器
大部分逻辑层优化器通过变换OperatorTree,合并操作符,达到减少MapReduce Job,减少shuffle数据量的目的。
② MapJoinProcessor
② GroupByOptimizer
① PredicatePushDown
ColumnPruner
名称 |
作用 |
---|---|
② SimpleFetchOptimizer |
优化没有GroupBy表达式的聚合查询 |
MapJoin,需要SQL中提供hint,0.11版本已不用 |
|
② BucketMapJoinOptimizer |
BucketMapJoin |
Map端聚合 |
|
① ReduceSinkDeDuplication |
合并线性的OperatorTree中partition/sort key相同的reduce |
谓词前置 |
|
① CorrelationOptimizer |
利用查询中的相关性,合并有相关性的Job,HIVE-2206 |
字段剪枝 |
表格中①的优化器均是一个Job干尽可能多的事情/合并。②的都是减少shuffle数据量,甚至不做Reduce。
CorrelationOptimizer优化器非常复杂,都能利用查询中的相关性,合并有相关性的Job,参考 Hive Correlation Optimizer
对于样例SQL,有两个优化器对其进行优化。下面分别介绍这两个优化器的作用,并补充一个优化器ReduceSinkDeDuplication的作用.
Phase5 - OperatorTree生成MapReduce Job的过程
OperatorTree转化为MapReduce Job的过程分为下面几个阶段
- 对输出表生成MoveTask
- 从OperatorTree的其中一个根节点向下深度优先遍历
- ReduceSinkOperator标示Map/Reduce的界限,多个Job间的界限
- 遍历其他根节点,遇过碰到JoinOperator合并MapReduceTask
- 生成StatTask更新元数据
- 剪断Map与Reduce间的Operator的关系
Phase6 - 物理层优化器
这里不详细介绍每个优化器的原理,单独介绍一下MapJoin的优化器
SortMergeJoinResolver
CommonJoinResolver + MapJoinResolver
名称 |
作用 |
---|---|
Vectorizer |
HIVE-4160,将在0.13中发布 |
与bucket配合,类似于归并排序 |
|
SamplingOptimizer |
并行order by优化器,在0.12中发布 |
MapJoin优化器 |
MapJoin原理
MapJoin简单说就是在Map阶段将小表读入内存,顺序扫描大表完成Join。
上图是Hive MapJoin的原理图,出自Facebook工程师Liyin Tang的一篇介绍Join优化的slice,从图中可以看出MapJoin分为两个阶段:
通过MapReduce Local Task,将小表读入内存,生成HashTableFiles上传至Distributed Cache中,这里会对HashTableFiles进行压缩。
MapReduce Job在Map阶段,每个Mapper从Distributed Cache读取HashTableFiles到内存中,顺序扫描大表,在Map阶段直接进行Join,将数据传递给下一个MapReduce任务。
如果Join的两张表一张表是临时表,就会生成一个ConditionalTask,在运行期间判断是否使用MapJoin
CommonJoinResolver优化器
CommonJoinResolver优化器就是将CommonJoin转化为MapJoin,转化过程如下
- 深度优先遍历Task Tree
- 找到JoinOperator,判断左右表数据量大小
- 对与小表 + 大表 => MapJoinTask,对于小/大表 + 中间表 => ConditionalTask
遍历上一个阶段生成的MapReduce任务,发现JOIN[8]
中有一张表为临时表,先对Stage-2进行深度拷贝(由于需要保留原始执行计划为Backup
Plan,所以这里将执行计划拷贝了一份),生成一个MapJoinOperator替代JoinOperator,然后生成一个MapReduceLocalWork读取小表生成HashTableFiles上传至DistributedCache中。
Operator在Map Reduce阶段之间的数据传递都是一个流式的过程。每一个Operator对一行数据完成操作后之后将数据传递给childOperator计算。
Operator类的主要属性和方法如下
- RowSchema表示Operator的输出字段
- InputObjInspector outputObjInspector解析输入和输出字段
- processOp接收父Operator传递的数据,forward将处理好的数据传递给子Operator处理
- Hive每一行数据经过一个Operator处理之后,会对字段重新编号,colExprMap记录每个表达式经过当前Operator处理前后的名称对应关系,在下一个阶段逻辑优化阶段用来回溯字段名
- 由 于Hive的MapReduce程序是一个动态的程序,即不确定一个MapReduce Job会进行什么运算,可能是Join,也可能是GroupBy,所以Operator将所有运行时需要的参数保存在OperatorDesc 中,OperatorDesc在提交任务前序列化到HDFS上,在MapReduce任务执行前从HDFS读取并反序列化。Map阶段 OperatorTree在HDFS上的位置在Job.getConf(“hive.exec.plan”)
+ “/map.xml” QueryBlock生成Operator Tree
QueryBlock生成Operator Tree就是遍历上一个过程中生成的QB和QBParseInfo对象的保存语法的属性,包含如下几个步骤:
- QB#aliasToSubq => 有子查询,递归调用
- QB#aliasToTabs => TableScanOperator
- QBParseInfo#joinExpr => QBJoinTree => ReduceSinkOperator + JoinOperator
- QBParseInfo#destToWhereExpr => FilterOperator
- QBParseInfo#destToGroupby => ReduceSinkOperator + GroupByOperator
- QBParseInfo#destToOrderby => ReduceSinkOperator + ExtractOperator
由于Join/GroupBy/OrderBy均需要在Reduce阶段完成,所以在生成相应操作的Operator之前都会先生成一个ReduceSinkOperator,将字段组合并序列化为Reduce Key/value, Partition Key
接下来详细分析样例SQL生成OperatorTree的过程
先序遍历上一个阶段生成的QB对象
转载于:https://www.cnblogs.com/yyy-blog/p/7077748.html
SQL转化为MapReduce的过程相关推荐
- Hive SQL转化为MapReduce的过程
编译 SQL 的任务是在 COMPILER(编译器组件)中完成的.Hive将SQL转化为MapReduce任务,整个编译过程分为六个阶段: 词法.语法解析: Antl ...
- Hadoop学习之Mapreduce执行过程详解
一.MapReduce执行过程 MapReduce运行时,首先通过Map读取HDFS中的数据,然后经过拆分,将每个文件中的每行数据分拆成键值对,最后输出作为Reduce的输入,大体执行流程如下图所示: ...
- Map-Reduce的过程解析
一.客户端 Map-Reduce的过程首先是由客户端提交一个任务开始的. 提交任务主要是通过JobClient.runJob(JobConf)静态函数实现的: public static Runnin ...
- SQL注入原理及产生过程
2019独角兽企业重金招聘Python工程师标准>>> 最近在学习关于SQL注入方面的知识,想将一些相关的知识点做个汇总和笔记,方便日后的查阅也方便现在的学习.因为刚开始学习,涉猎还 ...
- Hadoop学习总结:Map-Reduce的过程解析
一.客户端 Map-Reduce的过程首先是由客户端提交一个任务开始的. 提交任务主要是通过JobClient.runJob(JobConf)静态函数实现的: public static Runnin ...
- ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!)
原文:ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!) ORACLE PL/SQL编程之六: 把过程与函数说透(穷追猛打,把根儿都拔起!) 继上篇:ORACLE P ...
- 简述MapReduce执行过程?
简述MapReduce执行过程? Map把一个函数应用于集合中的所有成员,然后返回一个基于这个处理的结果集;Reduce是把两个或更多个Map中通过多个线程.进程或独立系统并行执行处理的结果集进行分类 ...
- 一条SQL查询语句的执行过程,一张图说清SQL查询语句执行过程
一张图说明 一条SQL查询语句的执行过程 一条sql语句从发送到数据库到它执行完成并返回结果,主要经历以下几个过程: 连接器->查询缓存(如果开启了查询缓存,则会经过这一步,但是大多数情况下都是 ...
- SQL Server 2008 R2 安装过程详解
SQL Server 是Microsoft 公司推出的关系型数据库管理系统.Microsoft SQL Server 是一个全面的数据库平台,使用集成的商业智能 (BI)工具提供了企业级的数据管理.M ...
最新文章
- 基于AI探索表观遗传药物发现的化学空间
- (转)layoutSubviews总结
- CPU缓存L1/L2/L3工作原理
- BUUCTF-Reverse:xor(涉及异或脚本编写)
- CSS3 -webkit-animation(动画)
- Material Design学习之 Snackbars(详细分析,Toast的加强版)
- 有监督学习和无监督学习举例_监督学习入门学习笔记
- 【C++】【Opencv】【vs2015】环境配置
- 一个简单的python登录验证系统
- 禾川plc编程软件_禾川PLC编程软件下载|HCP Works(禾川PLC编程软件) V2.26.01.92012 官方最新版 下载_当下软件园_软件下载...
- Safari浏览器中 视频倍速播放
- 一个软件完整的开发流程,不会程序也能自己制作手机App
- U-Net模型搭建python实现
- python中e怎么计算_蒙特卡洛法计算自然常数e——python编程及可视化
- Norms for Vectors and Matrices
- 点滴生活感悟(更新至29)
- 上传webshell(入侵目标页面主机靶机演示)
- Security Processor 周边
- 小学数学与计算机整合课优质教案,小学数学优质课教案《长方形的面积》(通用5篇)...
- 使用gcc编译STM32遇到的问题
热门文章
- java ssh shell命令_java 通过ssh 执行命令
- 华为cor—al10_cor al10是华为什么型号 cor al10是华为啥型号
- python 编辑excel需要什么包_Python 中操作EXCEL表格的包
- java都要caps标点_第 1 章 管理 Java CAPS 用户
- java 线程“生产/消费”模型1
- c++ socket学习(1.5)
- 使用Bootstrap-table创建表单,并且与flask后台进行数据交互
- 基于图像处理的数码印花喷墨墨滴形状规范的研究(Python+OpenCV+Mysql)
- 编写一个汇编语言程序,将字符串Hello World中的全部小写字母转换为大写字母,并存放回原地址处。
- JAVA JDK环境渲染