Job执行优化
Explain查询计划
FORMATTED:对执行计划进行格式化,返回JSON格式的执行计划 EXTENDED:提供一些额外的信息,比如文件的路径信息 DEPENDENCY:以JSON格式返回查询所依赖的表和分区的列表 AUTHORIZATION:列出需要被授权的条目,包括输入与输出
EXPLAIN [ FORMATTED| EXTENDED | DEPENDENCY| AUTHORIZATION ] SQL 语句
每个查询计划由三个部分组成:
抽象语法树(AST):Hive使用Antlr解析生成器,可以自动地将HQL生成为抽象语法树。 Stage依赖关系:会列出运行查询划分的stage阶段以及器之间的依赖关系。 Stage内容:包含了每个stage非常重要的信息,比如运行时的operator和sort orders等具体的信息。 例:
EXPLAIN SELECT COUNT ( * ) AS cnt FROM tb_emp WHERE deptno = '10' ;
MapReduce属性优化
本地模式
使用Hive的过程中,有一些数据量不大的表也会转换为MapReduce处理,提交到集群时,需要申请资源,等待资源分配,启动JVM进程,再运行Task,一系列的过程比较繁琐。而本地模式则是提供本地计算,程序不提交给YARN,提高小数据量程序的性能。 本地模式要求reduce task为1或0。 配置本地模式:
SET hive. exec . mode . local . auto = true ;
JVM重用
Hadoop默认会为每个Task启动一个JVM来运行,而在JVM启动时内存开销大; Job数据量大的情况下,如果单个Task数据量比较小,也会申请JVM,会导致资源紧张及浪费; JVM重用可以使得JVM实例在同一个job中重新使用N次,当一个Task运行结束以后,JVM不会进行释放,而是继续下一个Task运行,直到运行N个Task后才会释放。 N的值可以在Hadoop的mapred-site.xml文件中进行配置,通常在10-20之间。 Hadoop3之前版本的配置设置,之后版本不支持该选项:
mapreduce. job. jvm. numtasks= 10
并行执行
Hive在实现HQL计算运行时,会解析为多个Stage,有时Stage之间有依赖关系,只能挨个执行,但在一些别的场景下,很多Stage之间是没有依赖关系的。 配置设置:
SET hive. exec . parallel= true ;
SET hive. exec . parallel. thread. number= 16 ;
Join优化
小表Join大表:Map join 大表Join大表:Reduce join 大表Join的优化方案:Bucket join
Map Join
原理:小表数据给每个MapTask的内存都放一份完整的数据,大表数据的每个部分都可以于小数据的完整数据进行Join 底层不需要经过shuffle,需要占用内存空间存放小的数据文件 使用:(Hive默认开启了Map Join:hive.auto.convert.join=true) Hive中小表的大小控制
hive. mapjoin. smalltable. filesize= 25 M
hive. auto. convert . join . noconditionaltask. size= 512000000
Reduce Join
原理:将两张表的数据在shuffle阶段利用shuffle的分组来将数据按照关联字段进行合并(必须经过shuffle)。 使用:Hive会自动判断是否满足Map Join,如果不满足Map Join,则自动执行Reduce Join
Bucket Join
原理:将两张表按照相同的规则将数据划分,根据对应规则的数据进行join 分桶JOIN结合SORT排序效率更高 语法:
CLUSTERED BY colName SORTED BY ( colName)
SET hive. optimize . bucketmapjoin= true ;
SET hive. auto. convert . sortmerge. join = true ;
SET hive. optimize . bucketmapjoin. sortedmerge= true ;
SET hive. auto. convert . sortmerge. join . noconditionaltask= true ;
要求:分桶字段=Join字段,桶的个数相等或成倍数。
Job执行优化
关联优化
当一个程序中一些操作之间有关联性,可以在一个MapReduce中实现,但Hive仍然会使用两个MapReduce来完成这两个操作。 在Hive中开启关联优化后,会对有关联关系的操作进行解析,使其尽量放在同一个MapReduce中实现。 参数配置:
SET hive. optimize . correlation= true ;
优化器引擎
RBO
rule basic optimise:基于规则的优化器,根据设定好的规则对程序进行优化
CBO
cost basic optimise:基于代价的优化器,根据不同场景所需要付出的代价来选择合适的优化方案。 参数配置:
SET hive. cbo. enable = true ;
SET hive. compute . query. using . stats= true ;
SET hive. stats. fetch . column . stats= true ;
Analyze分析器
功能:用于提前运行一个MapReduce程序将表或者分区的信息构建一些元数据,搭配CBO引擎疫情使用。 语法:
ANALYZE TABLE tablename
[ PARTITION ( partcol1[ = val1] , partcol2[ = val2] , . . . ) ]
COMPUTE STATISTICS [ noscan] ;
ANALYZE TABLE tablename
[ PARTITION ( partcol1[ = val1] , partcol2[ = val2] , . . . ) ]
COMPUTE STATISTICS FOR COLUMNS ( columns name1, columns name2, . . . ) [ noscan] ;
DESC FORMATTED [ tablename] [ columnname] ;
谓词下推(PPD)
谓词:用来描述或判定客体性质、特征或客体之间关系的词项。("3大于2"中“大于”是谓词) 基本思想:将过滤表达式尽可能移动至靠近数据源的位置,以使真正执行时直接跳过无关数据;即在不影响最终结果的情况下,尽量将过滤条件提前执行。 Hive中谓词下推后,过滤条件会下推到map端,提前执行过滤,减少map到reduce的传输数据,提升整体性能。 已默认开启此配置 参数配置:
hive. optimize . ppd= true ;
规则:
对应Join[Inner]、Full outer Join,条件写在on后面和where后面性能上没有差别; 对于Left outer Join,右侧表写在on后面、左侧表写在where后面,性能上有提高; 对于Right outer Join,左侧表写在on后面,右侧表写在where后面,性能上有提高。 总结:先对主表where过滤,副表再on关联。(where先执行)
数据倾斜
数据倾斜现象是指当提交运行一个程序时,这个程序大多数的Task都已经运行结束了,只有某一个Task一直在运行,迟迟不能结束,导致整体的进度卡在99%,此时即可判定程序出现了数据倾斜问题。 原因:数据分配不均
Group by、Count()下的数据倾斜
当程序中出现group by或count(distinct)等分组聚合的场景时,如果数据本身是倾斜的(分区规则导致的),根据MapReduce的Hash分区规则,肯定会出现数据倾斜的现象。 解决方案:
开启Map端聚合:[hive.map.aggr=true;]
通过减少shuffle数据量和Reduce阶段的执行时间,避免每个Task数据差异过大导致数据倾斜。 实现随机分区:SELECT * FROM TABLE distribute BY rand();
数据倾斜时自动负载均衡:hive.groupby.skewindata=true;
开启该参数后,当前程序会自动通过两个MapReduce来运行。(空间换时间) 第一个MapReduce自动进行随机分布到Reducer中,每个Reduce做内部的局部聚合操作,输出结果 第二个MapReduce将上一步聚合的结果再按照业务(group by key)进行处理,保证相同的分布到一起,最后聚合得到结果。
Join下的数据倾斜
Join操作时,若两张表比较大,无法实现Map Join,只能用Reduce Join,则当关联字段中某一值过多时,会导致数据倾斜问题; 面对Join产生的数据倾斜,核心思想是尽量避免Reduce Join的产生,优先使用Map Join实现; 解决方案:
提前过滤,将大数据变成小数据,实现Map Join; 使用Bucket Join 将两张表数据构建为桶表,实现Bucket Map Join 使用Skew Join
原理:将Map Join和Reduce Join结合,若某个值出现了数据倾斜,就会将该数据单独使用Map Join来实现。其他没有数据倾斜的数据由Reduce Join实现。最终Map Join的结果和Reduce Join的结果进行Union合并。 参数配置:
SET hive. optimize . skewjoin= true ;
SET hive. skewjoin. key = 100000 ;
SET hive. optimize . skewjoin. compiletime= true ;
SET hive. optimize . union . remove= true ;
SET mapreduce. input. fileinputformat. input. dir. recursive= true ;