1 Explain
1.1 功能
HiveQL是一种类SQL的语言,从编程语言规范来说是一种声明式语言,用户会根据查询需求提
交声明式的HQL查询,而Hive会根据底层计算引擎将其转化成Mapreduce/Tez/Spark的 job。大多
数情况下,用户不需要了解Hive内部是如何工作的,不过,当用户对于Hive具有越来越多的经验后,
尤其是需要在做性能优化的场景下,就要学习下Hive背后的理论知识以及底层的一些实现细节,会
让用户更加高效地使用Hive。explain命令就可以帮助用户了解一条HQL语句在底层的实现过程
explain会解析HQL语句,将整个HQL语句的实现步骤、依赖关系、实现过程都会进行解析返
回,可以帮助更好的了解一条HQL语句在底层是如何实现数据的查询及处理的过程,这样可以辅助
用户对Hive进行优化。
官网:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Explain
1.2 语法
常用语法命令如下:
EXPLAIN [FORMATTED|EXTENDED|DEPENDENCY|AUTHORIZATION|] query
⚫ FORMATTED:对执行计划进行格式化,返回JSON格式的执行计划
⚫ EXTENDED:提供一些额外的信息,比如文件的路径信息
⚫ DEPENDENCY:以JSON格式返回查询所依赖的表和分区的列表
⚫ AUTHORIZATION:列出需要被授权的条目,包括输入与输出
1.3 组成
解析后的执行计划一般由三个部分构成,分别是:
⚫ The Abstract Syntax Tree for the query
◼ 抽象语法树:Hive使用Antlr解析生成器,可以自动地将HQL生成为抽象语法树
⚫ The dependencies between the different stages of the plan
◼ Stage依赖关系:会列出运行查询所有的依赖以及stage的数量
⚫ The description of each of the stages
◼ Stage内容:包含了非常重要的信息,比如运行时的operator和sort orders等具体的信息
4.1.4 示例1:过滤
explain select count ( * ) as cnt from tb_emp where deptno = ‘10’;
⚫ 组成
⚫ 解释
1.5 示例2:分组排序
explain
select
deptno, count ( * ) as cnt
from tb_emp where salary > 2000
group by deptno order by cnt desc;
2 MapReduce属性优化
2.1 本地模式
使用Hive的过程中,有一些数据量不大的表也会转换为MapReduce处理,提交到集群时,需
要申请资源,等待资源分配,启动JVM进程,再运行Task,一系列的过程比较繁琐,本身数据量并
不大,提交到YARN运行返回会导致性能较差的问题。
Hive为了解决这个问题,延用了MapReduce中的设计,提供本地计算模式,允许程序不提交
给YARN,直接在本地运行,以便于提高小数据量程序的性能。
⚫ 配置
– 开启本地模式
set hive.exec.mode.local.auto = true;
⚫ 限制条件
Hive为了避免大数据量的计算也使用本地模式导致性能差的问题,所以对本地模式做了以
下限制,如果以下任意一个条件不满足,那么即使开启了本地模式,将依旧会提交给YARN集
群运行。
◼ 处理的数据量不超过128M
◼ MapTask的个数不超过4个
◼ ReduceTask的个数不超过1个
2.2 JVM重用
JVM正常指代一个Java进程,Hadoop默认使用派生的JVM来执行map-reducer,如果一个
MapReduce程序中有100个Map,10个Reduce,Hadoop默认会为每个Task启动一个JVM来运行,
那么就会启动100个JVM来运行MapTask,在JVM启动时内存开销大,尤其是Job大数据量情况,如
果单个Task数据量比较小,也会申请JVM资源,这就导致了资源紧张及浪费的情况。
为了解决上述问题,MapReduce中提供了JVM重用机制来解决,JVM重用可以使得JVM实例在
同一个job中重新使用N次,当一个Task运行结束以后,JVM不会进行释放,而是继续供下一个Task
运行,直到运行了N个Task以后,就会释放,N的值可以在Hadoop的mapred-site.xml文件中进行
配置,通常在10-20之间。
⚫ 配置
– Hadoop3 之前的配置,在 mapred-site.xml 中添加以下参数
– Hadoop3 中已不再支持该选项
mapreduce.job.jvm.numtasks=10
2.3 并行执行
Hive在实现HQL计算运行时,会解析为多个Stage,有时候Stage彼此之间有依赖关系,只能挨
个执行,但是在一些别的场景下,很多的Stage之间是没有依赖关系的,例如Union语句,Join语句
等等,这些Stage没有依赖关系,但是Hive依旧默认挨个执行每个Stage,这样会导致性能非常差,
我们可以通过修改参数,开启并行执行,当多个Stage之间没有依赖关系时,允许多个Stage并行执
行,提高性能。
⚫ 配置
– 开启 Stage 并行化,默认为 false
SET hive.exec.parallel= true;
– 指定并行化线程数,默认为 8
.SET hive.exec.parallel.thread.number=16;
⚫ 注意:线程数越多,程序运行速度越快,但同样更消耗CPU资源
3 Join优化
3.1 Hive中的Join方案
表的Join是数据分析处理过程中必不可少的操作,Hive同样支持Join的语法,Hive Join的底层
还是通过MapReduce来实现的,Hive实现Join时,为了提高MapReduce的性能,提供了多种Join
方案来实现,例如适合小表Join大表的Map Join,大表Join大表的Reduce Join,以及大表Join的优
化方案Bucket Join等。
3.2 Map Join
⚫ 应用场景
适合于小表join大表或者小表Join小表
⚫ 原理
◼ 将小的那份数据给每个MapTask的内存都放一份完整的数据,大的数据每个部分都可以与
小数据的完整数据进行join
◼ 底层不需要经过shuffle,需要占用内存空间存放小的数据文件
⚫ 使用
◼ 尽量使用Map Join来实现Join过程
◼ Hive中默认自动开启了Map Join
– 默认已经开启了 Map Join
hive.auto.convert.join= true
◼ Hive中判断哪张表是小表及限制
LEFT OUTER JOIN的左表必须是大表
RIGHT OUTER JOIN的右表必须是大表
INNER JOIN左表或右表均可以作为大表
FULL OUTER JOIN不能使用MAPJOIN
MAPJOIN支持小表为子查询
使用MAPJOIN时需要引用小表或是子查询时,需要引用别名
在MAPJOIN中,可以使用不等值连接或者使用OR连接多个条件
在MAPJOIN中最多支持指定6张小表,否则报语法错误
◼ Hive中小表的大小限制
– 2.0 版本之前的控制属性
hive.mapjoin.smalltable.filesize=25M
– 2.0 版本开始由以下参数控制
hive.auto.convert.join.noconditionaltask.size=512000000
3.3 Reduce Join
⚫ 应用场景
适合于大表Join大表
⚫ 原理
◼ 将两张表的数据在shuffle阶段利用shuffle的分组来将数据按照关联字段进行合并
◼ 必须经过shuffle,利用Shuffle过程中的分组来实现关联
⚫ 使用
◼ Hive会自动判断是否满足Map Join,如果不满足Map Join,则自动执行Reduce Join