博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Hive SQL执行流程分析
阅读量:6976 次
发布时间:2019-06-27

本文共 4734 字,大约阅读时间需要 15 分钟。

转自  

最近在研究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;”实际执行的是:

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)        优化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

执行如下的查询:

SELECT uid, SUM(count) FROM logs GROUP BY uid

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

EXPLAIN SELECT uid, SUM(count) FROM logs GROUP BY uid;

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

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如下:

STAGE DEPENDENCIES:  Stage-1 is a root stage  Stage-0 is a root stageSTAGE 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

转载地址:http://tyupl.baihongyu.com/

你可能感兴趣的文章
全“芯”关注用户需求 AMD“超轻薄笔记本”杀出重围
查看>>
自定义通知与系统通知的学习(详解)
查看>>
软考新思维--2017年上半年信息系统项目管理师上午试题分析与答案(试题16-20题)...
查看>>
C#编码简单性之语义篇(如何编写简短的C#代码,随时更新)
查看>>
使用sudo进入root权限,以及防止root密码被恶意篡改
查看>>
Android 多媒体综述
查看>>
route命令相关整理
查看>>
关于VS2012如何安装Windows Phone Toolkit
查看>>
Forefront for OCS2007之部署
查看>>
IBM Thinkpad T43-44U 升级到 2G 内存后少了 66M
查看>>
【No.1_sizeof与strlen】
查看>>
SMO学习笔记(二)——还原(恢复)篇之完整恢复
查看>>
Windows Server 2003 AD升级到Windows Server 2008 AD的方法及详细步骤
查看>>
设置php-fpm使用socket文件
查看>>
用 Label 控制 Service 的位置 - 每天5分钟玩转 Docker 容器技术(106)
查看>>
Android美工坊:Selector选择器的使用
查看>>
Nginx&Apache&PHP参数汇总
查看>>
Android重绘ListView高度
查看>>
centos6 防火墙iptables操作整理
查看>>
Android 中文 API (25) —— ZoomControls
查看>>