1.Map执行前合并小文件
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat
说明:
在Map执行前合并小文件,减少Map数:CombineHiveInputFormat具有对小文件进行合并的功能(系统默认的格式)。HiveInputFormat没有对小文件合并功能。
2.map-reduce阶段合并小文件
hive.merge.mapfiles = true; – 默认true,在map-only任务结束时合并小文件hive.merge.mapredfiles = true; – 默认false,在map-reduce任务结束时合并小文件 hive.merge.size.per.task = 268435456; – 默认256M,合并文件的大小
hive.merge.smallfiles.avgsize = 16777216; – 当输出文件的平均大小小于该值时,启动一个独立的map-reduce任务进行文件merge
3.启用mapjoin优化
set hive.auto.convert.join.noconditionaltask=true;
set hive.auto.convert.join.noconditionaltask.size=比较大的值
说明:
开启map端join设置,这样可以将小表加载到内存,在map阶段完成join操作。
如果不指定MapJoin或者不符合MapJoin的条件,那么Hive解析器会将Join操作转换成Common Join,即:在Reduce阶段完成join。容易发生数据倾斜。可以用MapJoin把小表全部加载到内存在map端进行join,避免reducer处理。
4.out of memory和GC问题
解决内存溢出和GC问题,设置后运行时间缩短一倍
set mapreduce.map.memory.mb=4096; (container的内存)
set mapreduce.reduce.memory.mb=4096; (container的内存)
set mapreduce.map.java.opts=-Xmx3276M -Xms3276m -XX:+UseConcMarkSweepGC;
set mapreduce.reduce.java.opts=-Xmx3276M ;
----set mapreduce.map.java.opts=-Xmx3276M -Djava.net.preferIPv4Stack=true;
----set mapreduce.reduce.java.opts=-Xmx3276M -Djava.net.preferIPv4Stack=true;
-Xmx3276m:最大堆大小
-Xms3276m:初始堆大小,此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存
-XX:+UseConcMarkSweepGC:设置年老代为并发收集
说明:mapreduce内存默认为2g,堆外内存不超过map,reduce内存80%
在yarn container这种模式下,map/reduce task是运行在Container之中的,所以上面提到的mapreduce.map(reduce).memory.mb大小都大于mapreduce.map(reduce).java.opts值的大小。mapreduce.{map|reduce}.java.opts能够通过Xmx设置JVM最大的heap的使用,一般设置为0.75倍的memory.mb,因为需要为java code等预留些空间。
参考:https://www.cnblogs.com/parryyang/p/5750146.html
5.现网参数示例:
set hive.auto.convert.join=false;
set hive.optimize.skewjoin=true;
set hive.skewjoin.key=1000000; (默认值为100000)
set mapred.map.tasks=20;
set mapred.reduce.tasks=20;
set hive.merge.mapredfiles=false;
set hive.exec.parallel=true;
set hive.groupby.skewindata=true;
set mapreduce.map.memory.mb=8192;
set mapreduce.reduce.memory.mb=4096;
set mapreduce.map.java.opts=-Xmx6144M -Djava.net.preferIPv4Stack=true;
set mapreduce.reduce.java.opts=-Xmx3276M -Djava.net.preferIPv4Stack=true;
说明:
set hive.auto.convert.join=false;
在Hive v0.7之前,需要给出MapJoin的指示,Hive才会提供MapJoin的优化。
Hive v0.7之后的版本已经不需要给出MapJoin的指示就进行优化。它是通过如下配置参数来控制的:hive> set hive.auto.convert.join=true;hive 0.11之后,在表的大小符合设置时(hive.auto.convert.join.noconditionaltask=true,hive.auto.convert.join.noconditionaltask.size=10000,hive.mapjoin.smalltable.filesize=25000000), 默认会把join转换为map join(认 hive.ignore.mapjoin.hint为true,hive.auto.convert.join为true),不过hive0.11的 map join bug比较多,可以通过在默认关闭map join convert,在需要时再设置hint:hive.auto.convert.join=false 。hive.ignore.mapjoin.hint=false.
Hive v0.12.0版本,缺省状况下MapJoin优化是打开的。也就是hive.auto.convert.join=true。Hive还提供另外一个参数–表文件的大小作为开启和关闭MapJoin的阈值。hive.mapjoin.smalltable.filesize=25000000
参考:https://blog.youkuaiyun.com/weixin_39150719/article/details/102931864
set hive.optimize.skewjoin=true;
set hive.skewjoin.key=1000000; (默认值为100000)
在join过程中Hive会将计数超过阈值hive.skewjoin.key(默认100000 一般可以设置成处理的总记录数/reduce个数的2-4倍)的倾斜key对应的行临时写进文件中,然后再启动另一个job做map join生成结果
set hive.merge.mapredfiles=false;
hive.merge.mapfiles = true; – 默认true,在map-only任务结束时合并小文件hive.merge.mapredfiles = true; – 默认false,在map-reduce任务结束时合并小文件
set hive.exec.parallel=true;
控制在同一个sql中的不同的job是否可以同时运行,默认为false.
当多个子查询的结果需要join、union、union all的时候,该参数会让那些存在并发job的sql运行得更快,但同时消耗更多的资源。
参考:
https://blog.youkuaiyun.com/arlanhon/article/details/98481130
https://blog.youkuaiyun.com/yaoyaostep/article/details/50921786
set hive.groupby.skewindata=true;
第一个MRJob 中,Map的输出结果集合会随机分布到Reduce中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同的GroupBy Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的;第二个MRJob再根据预处理的数据结果按照GroupBy Key分布到Reduce中(这个过程可以保证相同的GroupBy Key被分布到同一个Reduce中),最后完成最终的聚合操作。