Hive sql编译过程

Hive在执行sql时会以MapReduce的方式对数据进行接入和处理,主要包含以下阶段:
在这里插入图片描述
Hive sql的执行及编译过程:

  1. Hive首先根据sql语句中的表从HDFS文件中获取数据,对数据文件进行split操作,使其可以一行一行将所需数据读入内存
  2. Map函数将内存中的数据按照key值进行映射,形成一行一行的key-value值
  3. 在实际应用中会有多台机器参与Map处理,Map完成后需要将带有相同key的数据分发到同一台集群去进行后续处理,此操作称为Shuffle
  4. 如果sql语句中包含有join、count、sum,还会进行reduce操作

在Hive底层,会将sql语句进行编译,其过程主要包含以下六点:
在这里插入图片描述
以查询语句为例,对5月30号的地区维表进行查询:

select * from dim.dim_region where dt = '2019-05-30'

【1】根据Antlr定义的sql语法规则,将相关sql进行词法、语法解析,转化为抽象语法树AST Tree

ABSTRACT SYNTAX TREE:
TOK_QUERY
    TOK_FROM 
    TOK_TABREF
           TOK_TABNAME
               dim
                 dim_region
    TOK_INSERT
      TOK_DESTINATION
          TOK_DIR
              TOK_TMP_FILE
        TOK_SELECT
          TOK_SELEXPR
              TOK_ALLCOLREF
        TOK_WHERE
          =
              TOK_TABLE_OR_COL
                  dt
                    '2019-05-30'

【2】遍历AST Tree,抽象出查询的基本组成单元QueryBlock
AST Tree生成后由于其复杂度依旧较高,不便于翻译为mapreduce程序,需要进行进一步抽象和结构化,形成QueryBlock。QueryBlock是一条SQL最基本的组成单元,包括三个部分:输入源,计算过程,输出。简单来讲一个QueryBlock就是一个子查询。QB的生成过程为一个递归过程,先序遍历 AST Tree ,遇到不同的Token 节点(理解为特殊标记),保存到相应的属性中,主要包含以下几个过程:

  • TOK_QUERY:创建 QB 对象,循环递归子节点
  • TOK_FROM:将表名语法部分保存到 QB 对象的 aliasToTabs 等属性中
  • TOK_INSERT:循环递归子节点
  • TOK_DESTINATION:将输出目标的语法部分保存在 QBParseInfo 对象的nameToDest 属性中
  • TOK_SELECT:分别将查询表达式的语法部分保存在 destToSelExpr 、destToAggregationExprs 、 destToDistinctFuncExprs 三个属性中
  • TOK_WHERE:将 Where 部分的语法保存在 QBParseInfo 对象的destToWhereExpr 属性中

【3】遍历QueryBlock,翻译为执行操作树OperatorTree
  Hive最终生成的MapReduce任务,Map阶段和Reduce阶段均由OperatorTree组成。逻辑操作符,就是在Map阶段或者Reduce阶段完成单一特定的操作。
  基本的操作符包括TableScanOperator,SelectOperator,FilterOperator,JoinOperator,GroupByOperator,ReduceSinkOperator。ReduceSinkOperator将Map端的字段组合序列化为Reduce Key/value, Partition Key,只可能出现在Map阶段,同时也标志着Hive生成的MapReduce程序中Map阶段的结束。
  Operator在MapReduce阶段之间的数据传递都是一个流式的过程。每一个Operator对一行数据完成操作后之后将数据传递给childOperator计算。由于Join/GroupBy/OrderBy均需要在Reduce阶段完成,所以在生成相应操作的Operator之前都会先生成一个ReduceSinkOperator,将字段组合并序列化为Reduce Key/value, Partition Key。

【4】Logical Optimizer对OperatorTree进行优化操作
  使用ReduceSinkOperator,减少shuffle数据量。大部分逻辑层优化器通过变换 OperatorTree ,合并操作符,达到减少 MapReduce Job ,减少 shuffle 数据量的目的。

【5】遍历OperatorTree,并翻译为MapReduce任务
OperatorTree 转化为 Task tree的过程分为下面几个阶段:

  1. 对输出表生成 MoveTask
  2. 从 OperatorTree 的其中一个根节点向下深度优先遍历
  3. ReduceSinkOperator 标示 Map/Reduce 的界限,多个 Job 间的界限
  4. 遍历其他根节点,遇过碰到 JoinOperator 合并 MapReduceTask
  5. 生成 StatTask 更新元数据
  6. 剪断 Map 与 Reduce 间的 Operator 的关系

【6】物理层优化器对MapReduce任务进行优化,生成最终的执行计划

发布了138 篇原创文章 · 获赞 45 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/ThreeAspects/article/details/104298284
今日推荐