hive 总体架构解析

来源:互联网 发布:charles游戏修改数据 编辑:程序博客网 时间:2024/06/04 22:55

最近整理了下自己以前的笔记,对Hive整体运行流程做了一些总结。

一、Hive简介和原理

       1)Hive起源

         Hive起源于FACEBOOK,由FACEBOOK的几名员工共同提出。最早提出的Hive概念来源于以下论文Hive——A Warehousing Solution Over A Map-Reduce Framework(论文见目录)。它是基于MapReduce框架的数据仓库的解决方案。主要解决了并行执行数据分析和机器查询的效率。Hive已经成为最流行的基于Hadoop的数据存储框架和数据分析框架,以及事实的大数据SQL标准和元数据标准;是Hadoop生态栈中最主要的基础架构。

         Hive主要是面向非专业人士,尤其是大数据分析师最好的工具。Hive的提供的功能非常健全,是效率最高、便于使用的作业提交工具。

简化后的HIVE架构:


     2)HIVE工作流


         HIVE的最小处理单元是OPERATORS ,OPERATORS(该术语来源于关系型数据中的术语,操作符。)可以是运行在集群的MAP任务,也可以是运行在集群的REDUCE任务,或者是运行在本地对于HDFS的操作;这些都会被抽象成OPERATORS。

         HIVE的COMPILER的作用是:把一条HIVE SQL,转换为一个OPERATORS的 图(这里大部分情况下会是一个树,树状结构)。

         HIVE中OPERATORS的种类:

OPERATORS

FUNCTION DESCRIBLE

缩写

TableScanOperator         

从表中读取数据                  

TS                     

ReduceSinkOperator       

把数据发送给Reduce端作聚合操作    

RS                     

JoinOperator                      

作两个表的关联操作Join            

JOIN                    

SelectOperator(投影)       

选择部分列并输出                    

SEL                  

   

FileSinkOperator      

建立结果数据并发送给文件         

FS                               

FilterOperator

过滤输入数据

FIL

GroupByOperator

对数据作Group By操作

GBY

MapJoinOperator

在内存中作大表和小表的关联操作

MapJOIN

LimitOperator

作limit,返回一定条目的数据

LIMIT

UnionOperator

作union

UNION


在较老的版本中,HIVE通常是一个MAPREDUCE作业(新版本可能是TEZ)。MAPPER是EXECMAPPER,REDUCER是EXECREDUCE。DRICVER实际上有多种处理模式,例如本地模式和分布式模式。

         在HIVE中最核心的模块就是COMPILER,它负责将一个字符串(HIVESQL),转化成一个执行计划。


简化后的执行流程图:



为了说明上述执行流程,需要辅助一个简单的Hive查询例子:

案例1-1:Hive执行以下语句:
INSERT OVERWRITE TABLE access_log_temp2
SELECT a.user, a.prono, a.maker, a.price FROM access_log_hbase a JOIN product_hbase p 
ON (a.prono = p.prono)


3)具体执行流程:

(1)Parser生成AST



HQL生成的语法解析树(AST):
HIVE主要是利用UNDERLER处理得到上面的抽象语法树(这棵抽象语法树主要是根据underller的分词规则来确定根结点和左右孩子的,Hive的这部分处理是利用underller进行的)。
(2)Semantic Analyzer生成Query Block(QB)


Tip:                                                                                                          
第二步会将抽象语法树按照QB的方式转换为由QB组成的树。通常情况下,每一个From子句会生成一个QB(Query Block)。通过查看具体有多少个QB就可查看Hive sql语句最终优化成多少个MapReduce的作业。

QB是由两个子数据结构组成即MetaData(元数据信息)和ParseInfo。语义分析的主要过程是向QB中填充元数据,另一个过程则是摘取AST的子节点,存储在ParseInfo中。Semantic Analyzer过程主要是经过以上两个过程,然后把QB关联起来形成一个由QB构成的图.

Logical Plan generator会将上一步生成的Query Block按照前文讲的几种的Operator,转换为Operator Tree。




由于Hive查询语句会将最后的查询结果写入到表access_log_temp2中,所以QB的MetaData中的Name To Destination…会转化为Operator Tree中的FileSinkOperator(文件下沉)。
最后会生成如下的OP Tree:

Logical Plan Generator (Result)

这里就得到了一个有向无环图(DAG),当在传统数据库中会对上图进行优化然后执行;而在Hadoop集群中这张图是不行的,因为在集群中执行需要对这张图进行优化、切片,分布式化转化为MapReduce作业然后执行。

(4)LOGICAL OPTIMIZER

         首先,Hive会对上图进行优化,重绘。

         这里需要介绍Hive中的优化器如下表:

优化器                    

简介                    

LineageGenerator                      

各个Operator血缘情况的设定,优化Operator的血缘关系           

 ColumnPruner        

列剪裁优化器                            

Predicate PushDown  

谓词下推优化器,将条件推到特定位置(where条件)            

PartitionPruner    

分区裁剪条件优化器                         

PartitionCondition Remove               

PartitionPruner消除无用的分支的优化器                     

GroupByOptimizer  

Group by优化两阶段中的Map端预阶段聚合的优化器                  

SamplePruner    

抽样优化器,降低抽样的数据量                      

MapJoinProcessor   

在特定的情况下,把JoinOperator改写成MapJoinOperator的          

优化器                                     

BucketMapJoin Optimizer               

对Bucket表做MapJoin的优化器                       

SortedMergeBucket MapJoinOptimizer               

对SortedMergeBucket进行MapJoin的优化器                

优化器                    

简介                               

UnionProcessor     

识别两边的子查询是否都是Map-Only的                 

JoinReader            

/*+ STREAMTABLE(A) */ 指定Join的               

ReduceSink                  

DeDuplication         

如果两个ReduceSink的操作符共享分区和排列顺序也一样,此时就可以将这两个表放在一起进行ReduceSink操作,提高效率。

上表中的优化器都是逻辑优化器。为了进一步介绍这些优化器,这里举个例子来进行说明。

         案例1-2 LOGICALOPTIMIZER(PREDIC PUSHDOWN)

         INSERTOVERWRITE TABLE access_log_temp2

         SELECTa.user, a.prono, a.maker, a.price FROM access_log_hbase a JOIN product_hbase p

                   ON(a.prono = p.prono) where p.mark = “honda”;

         此时,原来的逻辑计划图就会增加一个节点,如下图:


这是一个未进行优化的OP Tree,此时会存在一个问题:当access_log_hbase和product_hbase两个表的数据量非常大的时候,第三步进行的Join操作,就会产生海量的数之前就先进性过滤出”honda”的数据,此时向Reduce端发送的数据会变得很少,Join时数据也会变得很少,从而大幅度提高Hive SQL的执行效率。这一个优化的过程就叫做谓词下推,即把where选择过滤操作下推到合适的步骤进行。
进过谓词下推优化器优化后的OP Tree如下图:


(5)PHYSICAL PLAN GENERATOR 



物理执行计划会将OP Tree切成若干个Task,而一个Task就对应着一个MapReduce作业。由于案例中只有一个QB,所以最后会生成一个Task即一个MapReduce作业。
当DAG中存在Join或者Group By时,会在这个Operator之前的节点操作会在Map中执行,而这个Operator之后的节点都会在Reduce执行。而两者会通过ReduceSinkOperator操作来连接,这个操作符会将Map端的数据发送到Reduce端。


PHYSICAL PLAN GENERATOR (Result)


这样就将一个OP Tree转换为了一个Map-Red的作业。但是这个Map-Red作业还需要进行物理级别的优化。


(6)PHYSICAL OPTIMIZER
物理优化器


物理优化的类主要在Hive的org/apache/hadoop/hive/ql/optimizer/physical/包内。
主要有以下几个物理优化器。



i)以MapJoinResolver为例,介绍物理优化
请看下图(前例优化后的物理执行计划)

1.此时,只有Map过程,即在本地进行小表的压缩、上传;在服务端读大表然后进行关联。
2.在进行Join时,一般用户都会使用MapJoin来手动指令Select Map Join来进行操作。但是,如果用在进行Join时,用户并不知道哪个表大哪个表小也不知道该不该使用Map Join,此时使用CommonJoinResolver则会解决这一问题。首先不管表大还是表小,他都会对Task Tree做一定的优化,会在Join 的Map-Red Task之前加上一个conditional Task。当作业到执行到Conditional Task时,会在执行Join的Map-Red作业之前对表的大小先进行判断;如果表是大表则进行Join操作;当表是小表时则进行MapJoin操作。这样用户就不必关心表大还是小,也不需要关心具体执行过程。
这里把原来的物理计划中Join换成了MapJoin,从而避免了Map-Red过程,转换成为了只有Map过程的Task。从而避免了数据在各个节点之间的传输,大幅度提高了Task的执行效率。但是,这个物理执行计划的DAG是不能直接执行的,这里无法确定那个是大表,从而无法确定那个表要读入到内存。而物理优化器的作用就是对一个Task Tree(DAG)进行优化,选出读入内存的表,进行合理的优化提高执行效率。
具体转换过程见下图:

转换后Task Tree是由两个Task组成的DAG。第一个Task是在本地进行MapredLocalTask,首先会在本地读小表,然后把小表通过HashTableSinkOperator转换为一个Hashtable,然后打包、压缩,通过DistrubuteChach机制将其上传到服务器上。
在服务器上会先去读取大表,然后MapJoinOperator会去下载小表,然后将其读入到内存中,然后再内存中进行MapJoin。由于Map Join是在内存中进行的,并且此时只是均匀的去读一个大表,每个进程只读64M,可以在一个均匀的时间内完成Select并输出。此时只需要客户端都一个小表,服务器都一个大表完成MapJoin操作。
物理优化器的作用主要是改写Task Tree,根据不同的情况有不同的给些方式。详细内容请查看物理优化部分。

最后,来整体做个总结。
Hive 整体架构:



执行流程回顾:

补充:如何查看执行计划?
 只需要在Hive中执行的SQL语句前面加上EXPLAN语句。


**tip**

这里的总结都是我参加hive2.1培训的笔记(小象学院)。

虽然大体上对整个hive的执行流程做了个总结吧。但是对于初学者还是很难全部理解的,后面我会整理一些更细节的hive各个模块的具体理解内容。

原创粉丝点击