zoukankan      html  css  js  c++  java
  • Hive SQL编译过程

    antlr介绍

    Hive 使用 Antlr 实现 SQL 的词法和语法解析。Antlr 是一种语言识别工具,可以用来构造领域语言。Antrl 完成了词法分析、语法分析、语义分析、中间代码生成的过程。

    Antrl 的工作方式:编写一个语法文件,构造特定规则的语法,定义语法和词法规则完成最终的替换,生成代码。

    Hive 的语法规则和词法规则,都是定义在类似于 xxx.g 的文件中。其中:
    0.10X 版本以前:一个统一的语法和词法文件 hive.g
    0.11版本以后
    	定义词法规则:HiveLexer.g
    	定义语法规则:SelectClauseParser.g,FromClauseParser.g,IndentifiersParser.g,HiveParser.g
    

    Hive 接收到用户编写的 HQL,通过 antlr 进行解析生成代码。

    第一阶段:SQL 生成抽象语法树 ASTTree

    antlr 对 Hive SQL 解析的代码如下,HiveLexerX,HiveParser 分别是 antlr 对语法文件 Hive.g 编译后自动生成的词法解析和语法解析类,在这两个类中进行负责的解析。

    代码跳转关系:

    CliDriver.main();
    CliDriver.run();
    CliDriver.executeDriver();
    CliDriver.processLine()
    CliDriver.processCmd()
    CliDriver.processLocalCmd() # 完整的执行,输出过程
    Driver.run()
    Driver.runInternal() # 编译和执行
    Driver.compileInternal() # 编译
    Driver.compile() # 编译:SQL -> AST -> ResovleTree -> OperatorTree ->
    TaskTree
    ParseUtils.parse()
    ParseDriver.parse()
    

    image-20211101153418557

    第二阶段:SQL 基本组成单元 QueryBlock

    ASTTree 仍然非常复杂,不够结构化,不方便直接编译为 MapReduce 程序,ASTTree 转化为 QueryBlock 就是将 SQL 进一步抽象和结构化。

    QueryBLock 是一条 SQL 最基本单元,包括三个部分:输入源、计算过程、输出。QueryBlock 可理解子查询,详细源代码:

    org.apache.hadoop.hive.ql.parse.QB
    

    ASTTree 生成 QueryBlock 的过程是一个递归的过程,先顺序遍历ASTTree,遇到不同的 Token 节点,保存到相应的属性中,主要包含一下几个过程:

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

    第三阶段:逻辑操作符 Operator

    Hive 最终生成的 MapReduce 任务,Map 阶段和 Reduce 阶段均由 OperatorTree 组成。逻辑操作符,就是在 Map 阶段或者 Reduce 阶段完成单一特定的操作。

    基本操作符包括:TableScanOperator、SelectOperator、FilterOperator、JoinOperator、GroupByOperator、ReduceSinkOperator

    由于Join、GroupBy、OrderBy 均需要在 Reduce 阶段完成,所以在生成相应操作的 Operator 之前都会先生成一个 ReduceSinkOperator,将字段组合并序列化为 Reduce Key/value,Partition Key

    第四阶段:逻辑层优化器

    大部分逻辑层优化器通过变换 OperatorTree,合并操作符,达到减少MapReduce Job,减少 shuffle 数据量的目的。

    名称 作用
    ② SimpleFetchOptimizer 优化没有 GroupBy 表达式的聚合查询
    ② MapJoinProcessor MapJoin 需要 SQL 中提供 hint,0.11 版本已不用
    ② BucketMapJoinOptimizer BucketMapJoin
    ② GroupByOptimizer Map 端聚合
    ① ReduceSinkDeDuplication 合并线性的 OperatorTree 中 partition/sort key 相同的 Reduce
    ① PredicatePushDown 谓词前置、谓词下推
    ① CorrelationOptimizer 利用查询中的相关性,合并有相关性的 Job,Hive-2206
    ② ColumnPruner 字段剪枝

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

    PredicatePushDown 优化器:

    image-20211101152515470

    SQL 示例:谓词下推有些动作能限制性的话就尽量先执行。

    select a.*,b.* from a join b on a.id = b.id where b.id > 18;
    
    select a.*,c.* from a join (select b.* from b where b.id > 18) c on a.id = c.id
    

    第五阶段:OperatorTree 生成 MapReduce Job 过程

    OperatorTree 转化为 MapReduce Job 的过程分为一起阶段:

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

    第六阶段:物理层优化器

    MapJoin 优化器原理

    名称 作用
    VectorizerHIVE HIVE - 4160,在0.13中发布
    SortMergeJoinResolver 与 bucket 配合,类似于归并排序
    SamplingOptimizer 并行 order by 优化器,在 0.12中发布
    CommonJoinResolver + MapJoinResolver MapJoin 优化器
  • 相关阅读:
    Win8 消费者预览版中文版下载地址 官方原版
    Easyui datagrid加载本地Json数据
    myeclipse 8.510.0 安装 svn 方法
    easyui tree使用方法
    安装Oracle 11g r2先决条件检查失败解决方法
    Win8/Win7或XP 双系统安装图文教程
    Oracle存储过程与函数
    MyEclipse 中 使用 TortoiseSVN(1)
    MyEclipse 中 使用 TortoiseSVN(2)
    easyui使用Ajax提交表单,返回Json数据
  • 原文地址:https://www.cnblogs.com/starzy/p/15493938.html
Copyright © 2011-2022 走看看