SQL转化为MapReduce的过程

转载:http://www.cnblogs.com/yaojingang/p/5446310.html

在了解了MapReduce实现SQL基本操作之后,我们来看看Hive是如何将SQL转化为MapReduce任务的,整个编译过程分为六个阶段:

  1. Antlr定义SQL的语法规则,完成SQL词法,语法解析,将SQL转化为抽象语法树AST Tree
  2. 遍历AST Tree,抽象出查询的基本组成单元QueryBlock
  3. 遍历QueryBlock,翻译为执行操作树OperatorTree
  4. 逻辑层优化器进行OperatorTree变换,合并不必要的ReduceSinkOperator,减少shuffle数据量
  5. 遍历OperatorTree,翻译为MapReduce任务
  6. 物理层优化器进行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 => 分别将查询表达式的语法部分保存在destToAggregationExprsTOK_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

合并线性的OperatorTreepartition/sort key相同的reduce

谓词前置

① CorrelationOptimizer

利用查询中的相关性,合并有相关性的JobHIVE-2206

字段剪枝

表格中①的优化器均是一个Job干尽可能多的事情/合并。②的都是减少shuffle数据量,甚至不做Reduce。

CorrelationOptimizer优化器非常复杂,都能利用查询中的相关性,合并有相关性的Job,参考 Hive Correlation Optimizer

对于样例SQL,有两个优化器对其进行优化。下面分别介绍这两个优化器的作用,并补充一个优化器ReduceSinkDeDuplication的作用.

Phase5 -  OperatorTree生成MapReduce Job的过程

OperatorTree转化为MapReduce Job的过程分为下面几个阶段

  1. 对输出表生成MoveTask
  2. 从OperatorTree的其中一个根节点向下深度优先遍历
  3. ReduceSinkOperator标示Map/Reduce的界限,多个Job间的界限
  4. 遍历其他根节点,遇过碰到JoinOperator合并MapReduceTask
  5. 生成StatTask更新元数据
  6. 剪断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分为两个阶段:

  1. 通过MapReduce Local Task,将小表读入内存,生成HashTableFiles上传至Distributed Cache中,这里会对HashTableFiles进行压缩。

  2. MapReduce Job在Map阶段,每个Mapper从Distributed Cache读取HashTableFiles到内存中,顺序扫描大表,在Map阶段直接进行Join,将数据传递给下一个MapReduce任务。

如果Join的两张表一张表是临时表,就会生成一个ConditionalTask,在运行期间判断是否使用MapJoin

CommonJoinResolver优化器

CommonJoinResolver优化器就是将CommonJoin转化为MapJoin,转化过程如下

  1. 深度优先遍历Task Tree
  2. 找到JoinOperator,判断左右表数据量大小
  3. 对与小表 + 大表 => 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/392320.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用集合映射和关联关系映射_使用R进行基因ID映射

使用集合映射和关联关系映射Inter-conversion of gene ID’s is the most important aspect enabling genomic and proteomic data analysis. There are multiple tools available each with its own drawbacks. While performing enrichment analysis on Mass Spectrometry da…

leetcode 1018. 可被 5 整除的二进制前缀

给定由若干 0 和 1 组成的数组 A。我们定义 N_i:从 A[0] 到 A[i] 的第 i 个子数组被解释为一个二进制数(从最高有效位到最低有效位)。 返回布尔值列表 answer,只有当 N_i 可以被 5 整除时,答案 answer[i] 为 true&…

纯java应用搭建,16、BoneCp纯java项目使用

2、代码实现 package com.study;import com.jolbox.bonecp.BoneCP;import com.jolbox.bonecp.BoneCPConfig;import com.jolbox.bonecp.BoneCPDataSource;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.sql.*;/*** Boncp 纯java处理* CreateTime 2018/3/…

数据结构与算法深入学习_我最喜欢的免费课程,用于深入学习数据结构和算法...

数据结构与算法深入学习by javinpaul由javinpaul Data structures and algorithms are some of the most essential topics for programmers, both to get a job and to do well on a job. Good knowledge of data structures and algorithms is the foundation of writing go…

RabbitMQ学习系列(一): 介绍

1、介绍 RabbitMQ是一个由erlang开发的基于AMQP(Advanced Message Queue )协议的开源实现。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面都非常的优秀。是当前最主流的消息中间件之一。 RabbitMQ的官网:http…

详尽kmp_详尽的分步指南,用于数据准备

详尽kmp表中的内容 (Table of Content) Introduction 介绍 What is Data Preparation 什么是数据准备 Exploratory Data Analysis (EDA) 探索性数据分析(EDA) Data Preprocessing 数据预处理 Data Splitting 数据分割 介绍 (Introduction) Before we get into this, I want to …

leetcode 947. 移除最多的同行或同列石头(dfs)

n 块石头放置在二维平面中的一些整数坐标点上。每个坐标点上最多只能有一块石头。 如果一块石头的 同行或者同列 上有其他石头存在,那么就可以移除这块石头。 给你一个长度为 n 的数组 stones ,其中 stones[i] [xi, yi] 表示第 i 块石头的位置&#x…

matlab距离保护程序,基于MATLAB的距离保护仿真.doc

基于MATLAB的距离保护仿真摘要:本文阐述了如何利用Matlab中的Simulink及SPS工具箱建立线路的距离保护仿真模型,并用S函数编制相间距离保护和接地距离保护算法程序,构建相应的保护模块,实现了三段式距离保护。仿真结果表明&#xf…

ZOJ3385 - Hanami Party (贪心)

题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode3385 题目大意: 妖梦要准备一个party,所以需要许多食物,初始化妖梦的烹饪技能为L,每天妖梦有两种选择,一是选择当天做L个食物&am…

sklearn.fit_两个小时后仍在运行吗? 如何控制您的sklearn.fit。

sklearn.fitby Nathan Toubiana内森图比亚纳(Nathan Toubiana) 两个小时后仍在运行吗? 如何控制您的sklearn.fit (Two hours later and still running? How to keep your sklearn.fit under control) Written by Gabriel Lerner and Nathan Toubiana加布里埃尔勒纳…

RabbitMQ学习系列(二): RabbitMQ安装与配置

1.安装 Rabbit MQ 是建立在强大的Erlang OTP平台上,因此安装RabbitMQ之前要先安装Erlang。 erlang:http://www.erlang.org/download.html rabbitmq:http://www.rabbitmq.com/download.html 注意: 1.现在先别装最新的 3…

帝国CMS浅浅滴谈一下——博客园老牛大讲堂

封笔多月之后,工作中遇到了很多很多的问题,也解决了一些问题,下面我把一些得出的经验,分享给大家! 会帝国cms的请离开,这篇文章对你没什么用 1、什么是帝国CMS?---博客园老牛大讲堂 多月之前&am…

matlab cdf,Matlab 简单计算PDF和CDF | 学步园

通信的魅力就是在于随机性中蕴含的确定性,这也就是为什么你随便拿出一本通信方面的教材,前面几章都会大篇幅的讲解随机过程,随机过程也是研究生必须深入了解的一门课,特别是对于信号处理以及通信专业的学生。在实际工作中&#xf…

leetcode 1232. 缀点成线

在一个 XY 坐标系中有一些点,我们用数组 coordinates 来分别记录它们的坐标,其中 coordinates[i] [x, y] 表示横坐标为 x、纵坐标为 y 的点。 请你来判断,这些点是否在该坐标系中属于同一条直线上,是则返回 true,否则…

mysql常用操作(一)

【数据库设计的三大范式】1、第一范式(1NF):数据表中的每一列,必须是不可拆分的最小单元。也就是确保每一列的原子性。 例如:userInfo:山东省烟台市 18865518189 应拆分成 userAds山东省烟台市 userTel188655181892、第…

pmp 成本估算准确高_如何更准确地估算JavaScript中文章的阅读时间

pmp 成本估算准确高by Pritish Vaidya通过Pritish Vaidya 准确估算JavaScript中篇文章的阅读时间 (Accurate estimation of read time for Medium articles in JavaScript) 介绍 (Introduction) Read Time Estimate is the estimation of the time taken by the reader to rea…

Android数据适配-ExpandableListView

Android中ListView的用法基本上学的时候都会使用,其中可以使用ArrayAdapter,SimpleAdapter,BaseAdapter去实现,这次主要使用的ExpandableListView展示一种两层的效果,ExpandableListView是android中可以实现下拉list的…

JavaWeb 命名规则

命名规范命名规范命名规范命名规范 本规范主要针对java开发制定的规范项目命名项目命名项目命名项目命名 项目创建,名称所有字母均小写,组合方式为:com.company.projectName.component.hiberarchy。1. projectName:项目名称2. com…

多元概率密度_利用多元论把握事件概率

多元概率密度Humans have plenty of cognitive strengths, but one area that most of us struggle with is estimating, explaining and preparing for improbable events. This theme underpins two of Nassim Taleb’s major works: Fooled by Randomness and The Black Swa…

nginx php访问日志配置,nginx php-fpm 输出php错误日志的配置方法

由于nginx仅是一个web服务器,因此nginx的access日志只有对访问页面的记录,不会有php 的 error log信息。nginx把对php的请求发给php-fpm fastcgi进程来处理,默认的php-fpm只会输出php-fpm的错误信息,在php-fpm的errors log里也看不…