`

Hive SQL解析/执行计划生成流程分析

    博客分类:
  • hive
 
阅读更多
转载:
http://blog.csdn.net/wf1982/article/details/9122543


Hive SQL解析/执行计划生成流程分析
近在研究Impala,还是先回顾下Hive的SQL执行流程吧。

Hive有三种用户接口:

cli (Command line interface) bin/hive或bin/hive –service cli 命令行方式(默认)
hive-server/hive-server2 bin/hive –service hiveserver 或bin/hive –service hiveserver2 通过JDBC/ODBC和Thrift访问(Impala通过这种方式借用hive-metastore)
hwi (Hive web interface) bin/hive –service hwi 通过浏览器访问


在hive shell中输入“show tables;”实际执行的是:


1

bin/hadoop

jar hive/lib/hive-cli-0.9.0.jar
org.apache.hadoop.hive.cli.CliDriver -e 'SHOW
TABLES;'
CLI入口函数:cli.CliDriver.main()

读入参数->建立SessionState并导入配置->处理输入文件中指令CliDriver.processFile();或交互型指令CliDriver.processLine()->解析输入CliDriver.processCmd()

(1) 如果是quit或者exit,退出

(2) 以source开头的,读取外部文件并执行文件中的HiveQL

(3) !开头的命令,执行操作系统命令(如!ls,列出当前目录的文件信息)

(4) list,列出jar/file/archive

(5) 其他命令,则生成调用相应的CommandProcessor处理,进入CliDriver.processLocalCmd()

下面看看CliDriver.processLocalCmd()这个函数:

set/dfs/add/delete指令交给指定的CommandProcessor处理,其余的交给org.apache.hadoop.hive.ql.Driver.run()处理

org.apache.hadoop.hive.ql.Driver类是查询的起点,run()方法会先后调用compile()和execute()两个函数来完成查询,所以一个command的查询分为compile和execute两个阶段。

Compile

(1)利用antlr生成的HiveLexer.java和HiveParser.java类,将HiveQL转换成抽象语法树(AST)。

首先使用antlr工具将srcqlsrcjavaorgapachehadoophiveqlparsehive.g编译成以下几个文件:HiveParser.java, Hive.tokens, Hive__.g, HiveLexer.java

HiveLexer.java和HiveParser.java分别是词法和语法分析类文件,Hive__.g是HiveLexer.java对应的词法分析规范,Hive.tokens定义了词法分析后所有的token。

然后沿着“Driver.compile()->ParseDriver.parse(command, ctx)->HiveParserX.statement()->antlr中的API”这个调用关系把输入的HiveQL转化成ASTNode类型的语法树。HiveParserX是由antlr生成的HiveParser类的子类。

(2)利用对应的SemanticAnalyzer类,将AST树转换成Map-reduce task。主要分为三个步骤:

a) AST -> operator DAG

b) optimize operator DAG

c) oprator DAG -> Map-reduce task

首先接着上一步生成的语法树ASTNode, SemanticAnalyzerFactory会根据ASTNode的token类型生成不同的SemanticAnalyzer (所有这些SemanticAnalyzer都继承自BaseSemanticAnalyzer)

1) ExplainSemanticAnalyzer

2) LoadSemanticAnalyzer

3) ExportSemanticAnalyzer

4) DDLSemanticAnalyzer

5) FunctionSemanticAnalyzer

6) SemanticAnalyzer

然后调用BaseSemanticAnalyzer.analyze()->BaseSemanticAnalyzer. analyzeInternal()。

下面以最常见的select * from table类型的查询为例,进入的子类是SemanticAnalyzer. analyzeInternal(),这个函数的逻辑如下:

1) doPhase1():将sql语句中涉及到的各种信息存储起来,存到QB中去,留着后面用。

2) getMetaData():获取元数据信息,主要是sql中涉及到的 表 和 元数据 的关联

3) genPlan():生成operator tree/DAG

4) optimize:优化,对operator tree/DAG 进行一些优化操作,例如列剪枝等(目前只能做rule-based optimize,不能做cost-based optimize)

5) genMapRedTasks():将operator tree/DAG 通过一定的规则生成若干相互依赖的MR任务

Execute

将Compile阶段生成的task信息序列化到plan.xml,然后启动map-reduce,在configure时反序列化plan.xml

实例分析:

在hive中有这样一张表:

uid

fruit_name

count

a

apple

5

a

orange

3

a

apple

2

b

banana

1

执行如下的查询:


1

SELECT

uid, SUM(count)
FROM

logs GROUP

BY
uid


通过explain命令可以查看执行计划:


1

EXPLAIN
SELECT

uid, SUM(count)
FROM

logs GROUP

BY
uid;
依照hive.g的语法规则,生成AST如下:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

ABSTRACT
SYNTAX TREE:

(

  TOK_QUERY

  (TOK_FROM
(TOK_TABREF (TOK_TABNAME logs)))

  (

    TOK_INSERT

    (TOK_DESTINATION
(TOK_DIR TOK_TMP_FILE))

    (

      TOK_SELECT

      (TOK_SELEXPR
(TOK_TABLE_OR_COL uid))

      (TOK_SELEXPR
(TOK_FUNCTION sum

(TOK_TABLE_OR_COL count)))

    )

    (TOK_GROUPBY
(TOK_TABLE_OR_COL uid))

  )

)


生成的执行计划operator tree/DAG如下:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

STAGE
DEPENDENCIES:

  Stage-1
is

a root stage

  Stage-0
is

a root stage



STAGE
PLANS:

  Stage:
Stage-1

    Map
Reduce

      Alias
-> Map Operator Tree:

        logs

          TableScan
// 扫描表

            alias:
logs

            Select

Operator //选择字段

              expressions:

                    expr:
uid

                    type:
string

                    expr:
count

                    type:
int

              outputColumnNames:
uid, count

              Group

By
Operator //在map端先做一次聚合,减少shuffle数据量

                aggregations:

                      expr:
sum(count)
//聚合函数

                bucketGroup:
false

                keys:

                      expr:
uid

                      type:
string

                mode:
hash

                outputColumnNames:
_col0, _col1

                Reduce
Output

Operator //输出key,value给reduce

                  key

expressions:

                        expr:
_col0

                        type:
string

                  sort
order:
+

                  Map-reduce
partition columns:

                        expr:
_col0

                        type:
string

                  tag:
-1

                  value
expressions:

                        expr:
_col1

                        type:
bigint

      Reduce
Operator Tree:

        Group

By
Operator

          aggregations:

                expr:
sum(VALUE._col0)
//聚合

          bucketGroup:
false

          keys:

                expr:
KEY._col0

                type:
string

          mode:
mergepartial

          outputColumnNames:
_col0, _col1

          Select

Operator //选择字段

            expressions:

                  expr:
_col0

                  type:
string

                  expr:
_col1

                  type:
bigint

            outputColumnNames:
_col0, _col1

            File
Output

Operator //输出到文件

              compressed:
false

              GlobalTableId:
0

              table:

                  input
format: org.apache.hadoop.mapred.TextInputFormat

                  output

format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat



  Stage:
Stage-0

    Fetch

Operator

      limit:
-1
Hive优化策略:

1. 去除查询中不需要的column

2. Where条件判断等在TableScan阶段就进行过滤

3. 利用Partition信息,只读取符合条件的Partition

4. Map端join,以大表作驱动,小表载入所有mapper内存中

5. 调整Join顺序,确保以大表作为驱动表

6. 对于数据分布不均衡的表Group by时,为避免数据集中到少数的reducer上,分成两个map-reduce阶段。第一个阶段先用Distinct列进行shuffle,然后在reduce端部分聚合,减小数据规模,第二个map-reduce阶段再按group-by列聚合。

7. 在map端用hash进行部分聚合,减小reduce端数据处理规模。

参考文献:

http://fatkun.com/2013/01/hive-group-by.html

更多 0
分享到:
评论

相关推荐

    Hive SQL 编译过程详解

    2.1 Phase1 SQL词法,语法解析 2.1.1 Antlr 2.1.2 抽象语法树AST Tree 2.1.3 样例SQL ........... 2.3 Phase3 逻辑操作符Operator ........... 2.4 Phase4 逻辑层优化器 ........... 2.5 Phase5 OperatorTree生成...

    HiveSQL编译原理.pdf

    Hive的核心原理讲解,主要讲述Hive解析编译SQL语句,生成执行计划的过程。文档涉及关键代码说明。

    sql解析,hql解析,hive脚本转mysql,解析hive,sparkSql,ER图自动生成、Excel自动生成.zip

    sql解析,hql解析,hive脚本转mysql,解析hive,sparkSql,ER图自动生成、Excel自动生成.zip

    hive学习和习题集

    (2)编译器(Physical Plan):将AST编译生成逻辑执行计划。 (3)优化器(Query Optimizer):对逻辑执行计划进行优化。 (4)执行器(Execution):把逻辑执行计划转换成可以运行的物理计划。对于Hive来说,就是...

    基于SpringBoot+hiveJDBC+echarts的数据大屏可视化和大数据分析源码+项目使用说明.zip

    SpringBoot整合HiveJdbc, 远程连接HiveServer2,并结合Java和HiveSQL 对存储在Hadoop 的6万条电商数据,进行数据分析。后端生成Json 格式,前端解析Json格式,并实现数据大屏可视化。 通过大数据分析,生成有价值...

    hive3.1.0-antrl3.5.2-Hivegrammar源码.zip

    HiveSql后续的编译过程全都基于AST Tree,所以我们想要完整理解hive sql的编译过程,需要前置了解一下antlr是怎么工作的。 HiveLexer.g:词法解析文件,定义了所有用到的token。 HiveParser.g:语法解析文件,实现了...

    hive-exec-2.1.1.jar

    这个组件负责解析 SQL 查询,生成执行计划,并协调与 Hadoop 集群的交互以执行这些计划。它还包括了用于数据处理的逻辑和与 Hadoop 组件(如 MapReduce、Tez 或 Spark)的集成。 具体来说,hive-exec 可能包括以下...

    dt-sql-parser:使用antlr4构建的BigData SQL解析器

    支持SQL: MySQL Flink SQL Spark SQL Hive SQL PL / SQL 提示:该项目是Javascript语言的默认项目,如果需要,您也可以尝试将其编译为其他语言。安装// use npmnpm i dt-sql-parser --save// use yarnyarn add dt-...

    大数据时代基于Hadoop的一个数据仓库工具hive

    1. Driver 组件:解析、编译优化 HiveQL 语句,生成执行计划,然后调用底层的 MapReduce 计算框架 2. Metastore 组件:元数据服务组件,存储 Hive 的元数据 3. Thrift 服务:让不同的编程语言调用 Hive 的接口 4. ...

    Quicksql:用于多个数据源的灵活,快速,联合(3F)SQL分析中间件

    解析层:用于解析,验证,优化SQL语句,拆分混合SQL并最终生成查询计划; 计算层:用于将查询计划路由到特定执行计划,然后解释为给定存储或引擎的可执行代码(例如Elasticsearch JSON查询或Hive HQL); 存储层...

    antlrworks-1.5.1.jar

    HiveSql后续的编译过程全都基于AST Tree,所以我们想要完整理解hive sql的编译过程,需要前置了解一下antlr是怎么工作的。通过ANTLRWorks可以更加直观的理解解析过程。 对ANTLR的支持——源代码图。编辑ANTLR语法文件...

    word分词器java源码-hive_ql_parser:hive_ql_parser

    本文可以作为antlr实现的高级进阶教程,亦可以作为hive的源码分析教程,毕竟,语法词法解析,执行计划的生成优化以及执行也是hive的核心。这不是定位不清晰,而是我有这样的需求,既想了解antlr的具体使用,又想深入...

    sql-metadata:使用python-sqlparse返回的标记化查询并生成查询元数据

    提供用于标准化SQL查询和表别名解析的帮助器。 支持的查询语法: MySQL PostgreSQL 用法 pip install sql_metadata >> > import sql_metadata >> > sql_metadata . get_query_tokens ( "SELECT * FROM foo" ) [ ...

    SparkSql技术

    1.2.2:字节码生成技术(bytecode generation,即CG) 6 1.2.3:scala代码优化 7 二:sparkSQL运行架构 8 2.1:Tree和Rule 9 2.1.1:Tree 10 2.1.2:Rule 10 2.2:sqlContext的运行过程 12 2.3:hiveContext的运行...

    Presto在有赞的实践之路

    Presto是由Facebook开发的开源大数据分布式高性能SQL查询引擎。起初,Facebook使用Hive来进行交互式查询分析,但...语义解析后的数据生成逻辑执行计划,并且通过规则进行优化。切分逻辑执行计划为不同Stage,并调度Wor

    硬核剖析三大运营商电信信号强度诊断项目实战视频教程

    为了不影响线上系统的正常使用,同时能够将数据发送到大数据平台,本项目使用Canal来解析实时数据,Flume收集数据并数据发送到实时计算业务流程和离线计算两个流程中。实时数据处理流程使用Canal+Flume+Kafka+Spark...

    antlr4权威指南

    ANTLR是一款强大的语法分析器生成工具,可用于读取、处理、执行和翻译结构化的文本或二进制文件。它被广泛应用于学术领域和工业生产实践,是众多语言、工具和框架的基石。Twitter搜索使用ANTLR进行语法分析,每天...

    antlr-repackaged-4.0.jar

    antlr是指可以根据输入自动生成语法树并可视化的显示出来的开源语法分析器。ANTLR—Another Tool for Language Recognition,其前身是PCCTS,它为包括Java,C++,C#在内的语言提供了一个通过语法描述来自动构造...

    antlr-3.4.jar

    antlr是指可以根据输入自动生成语法树并可视化的显示出来的开源语法分析器。ANTLR—Another Tool for Language Recognition,其前身是PCCTS,它为包括Java,C++,C#在内的语言提供了一个通过语法描述来自动构造...

Global site tag (gtag.js) - Google Analytics