Hive学习解析之工作原理.md

简介

Hive可以快速实现简单的MapReduce统计,主要是通过自身组件把HiveQL转换成MapReduce任务来实现的。

Hive中SQL查询转换成MapReduce作业的过程

  • 当用户向 Hive 输入一段命令或查询(即 HiveQL 语句)时,Hive 需要与 Hadoop 交互工作来完成该操作。
  • 该命令或查询首先进入到驱动模块,由驱动模块中的编译器进行解析编译,并由优化器对该操作进行优化计算,然后交给执行器去执行。执行器通常的任务是启动一个或多个 MapReduce 任务,有时也不需要启动 MapReduce 任务。

例:
执行包含*的操作时(如 select * from 表),就是全表扫描,选择所有的属性和所有的元组,不存在投影和选择操作,因此,不需要执行 Map 和 Reduce 操作。

HiveQL 执行流程

 

Hive中SQL查询的MapReduce作业转化过程
Hive中SQL查询的MapReduce作业转化过程

 

HiveQL执行流程步骤解析

  1. 由 Hive 驱动模块中的编译器——Antlr 语言识别工具,对用户输入的 SQL 语言进行词法和语法解析,将 SQL 语句转化为抽象语法树(AST Tree)的形式;
  2. 对该抽象语法树进行遍历,进一步转化成 QueryBlock 查询单元。因为抽象语法树的结构仍很复杂,不方便直接翻译为 MapReduce 算法程序,所以,Hive 把抽象语法树进一步转化为 QueryBlock,其中,QueryBlock 是一条最基本的 SQL 语法组成单元,包括输入源、计算过程和输出三个部分;
  3. 再对 QueryBlock 进行遍历,生成 OperatorTree(操作树)。其中,OperatorTree由很多逻辑操作符组成,如 TableScanOperator、SelectOperator、FilterOperator、JoinOperator、GroupByOperator 和 ReduceSinkOperator 等。这些逻辑操作符可以在 Map 阶段和 Reduce 阶段完成某一特定操作;
  4. 通过 Hive 驱动模块中的逻辑优化器对OperatorTree 进行优化,变换 OperatorTree的形式,合并多余的操作符,从而减少 MapReduce 任务数量以及 Shuffle 阶段的数据量;
  5. 对优化后的 OperatorTree 进行遍历,根据 OperatorTree 中的逻辑操作符生成需要执行的 MapReduce 任务;
  6. 启动 Hive 驱动模块中的物理优化器,对生成的 MapReduce 任务进行优化,生成最终的 MapReduce 任务执行计划;
  7. 最后由 Hive 驱动模块中的执行器,对最终的 MapReduce 任务进行执行输出。

总结

Hive驱动模块中的执行器执行最终的MapReduce任务时,Hive本身是不会生成MapReduce算法程序的,他需要通过一个表示“Job执行计划”的XML文件来驱动执行内置的、原生的Mapper和Reducer模块。
Hive通过和JobTracker通信来初始化MapReduce任务,不需要直接部署在JobTracker所在的管理节点上执行。Hive要处理的数据文件通常存储在HDFS上,HDFS是由NameNode来管理的。

HiveSQL执行查询语句实例

1. 用MapReduce实现连接操作

假设参与连接(join)的两个表分别为用户表 User 和订单表 Order,User 表有两个属性,
即 uid 和 name,Order 表也有两个属性,即 uid 和 orderid,它们的连接键为公共属性 uid。
这里对两个表执行连接操作,得到用户的订单号与用户名的对应关系。
SQL查询语句如下:

    select name, orderid from user u join order o on u.uid=o.uid;

 

连接执行过程
连接执行过程

 

过程说明:

  1. 在Map阶段,User 表以 uid 为键(key),以 name 和表的标记位(这里 User 的标记位记为 1)为值(value)进行 Map 操作,把表中记录转化成生成一系列键值对的形式。Order 表以 uid 为键,以 orderid 和表的标记位(这里表 Order 的标记位记为 2)为值进行 Map 操作,把表中记录转化成生成一系列键值对的形式。
    例:
    User 表中记录(1,Lily)转化为键值对(1,<1,Lily>),其中,括号中的第一个“1”是 uid 的值,第二个“1”是表 User 的标记位,用来标识这个键值对来自 User 表;再比如,Order 表中记录(1,101)转化为键值对(1,<2,101>),其中,“2”是表 Order 的标记位,用来标识这个键值对来自 Oder 表。

  2. Shuffle阶段,把 User 表和 Order 表生成的键值对按键值进行哈希,然后传送给对应的 Reduce 机器执行。
    例:
    比如键值对(1,<1,Lily>)、(1,<2,101>)和 (1,<2,102>)传送到同一台 Reduce 机器上,键值对
    (2,<1,Tom>)和(2,<2,103>)传送到另一台 Reduce 机器上。当Reduce机器接收到这些键值对时,还需要按表的标记位对这些键值对进行排序,以优化连接操作。

  3. Reduce阶段,对同一台 Reduce 机器上的键值对,根据“值”(value)中的表标记位,对来自 User 和 Order这两个表的数据进行笛卡尔积连接操作,以生成最终的连接结果。
    例:
    键值对(1,<1,Lily>)与键值对(1,<2,101>)和 (1,<2,102>)的连接结果分别为(Lily ,101>)和 (Lily, 102),键值对(2,<1,Tom>)和键值对(2,<2,103>)的连接结果为(Tom, 103)。

2. 用MapReduce实现分组操作

假设分数表 Score 具有两个属性,即 rank(排名)和 level(级别),这里存在一个分组
(Group By)操作,其功能是把表 Score 的不同片段按照 rank 和 level 的组合值进行合并,计算不同 rank 和 level 的组合值分别有几条记录。
SQL查询语句如下:

    select rank, level ,count(*) as value from score group by rank, level;

 

分组执行过程
分组执行过程

 

过程说明:

  1. Map阶段,对表 Score 进行 Map 操作,生成一系列键值对,对于每个键值对,其键为“<rank,level>”,值为“拥有该<rank,value>组合值的记录的条数”。
    例:
    Score 表的第一片段中有两条记录(A,1),所以,记录(A,1)转化为键值对(<A,1>,2),Score 表的第二片段中只有一条记录(A,1),所以,记录(A,1)转化为键值对(<A,1>,1)。

  2. Shuffle阶段,对 Score 表生成的键值对,按照“键”的值进行哈希,然后根据哈希结果传送给对应的 Reduce 机器去执行。
    例:
    键值对(<A,1>,2)和 (<A,1>,1)传送到同一台Reduce机器上,键值对(<B,2>,1)传送到另一台Reduce机器上。然后,Reduce 机器对接收到的这些键值对,按“键”的值进行排序。

  3. Reduce阶段,对于 Reduce 机器上的这些键值对,把具有相同键的所有键值对的“值”进行累加,生成分组的最终结果。
    例:
    在同一台 Reduce 机器上的键值对(<A,1>,2)和 (<A,1>,1>)Reduce后的输出结果为(A,1,3),(<B,2>,1)的 Reduce 后的输出结果为(B,2,1)。

参考:

厦门大学林子雨编著-大数据技术原理与应用-电子书-第14章-基于Hadoop的数据仓库Hive(2016年4月6日版本).pdf

posted @ 2019-11-27 15:16  音译昌  阅读(504)  评论(0编辑  收藏  举报