目录

排序优化

用DISTRIBUTE BY和Sort by关键字代替Order by

分为扫描

对列使用分区

尽量启用本地模式

设置并行模式

启用严格模式

jvm重用

正常情况下,MapReduce启动的JVM在完成一个task之后就退出了,但是如果任务花费时间很短,又要多次启动JVM的情况下(比如对很大数据量进行计数操作),JVM的启动时间就会变成一个比较大的消耗。在这种情况下,可以使用jvm重用的参数:

set mapred.job.reuse.jvm.num.tasks = 5;

他的作用是让一个jvm运行多次任务之后再退出。这样一来也能节约不少JVM启动时间。

桶表

创建一个桶表
create table t4 (name string,age int,id int) CLUSTERED BY (id) SORTED BY (id) INTO 10 BUCKETS ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

可以自动控制reduce的数量从而适配bucket的个数,当然,用户也可以自主设置mapred.reduce.tasks去适配bucket个数,推荐使用'set hive.enforce.bucketing = true'  
set hive.enforce.bucketing=true;

Sorted Merge Bucket Map Join Operator依赖参数

查看执行计划

数据倾斜

数据倾斜分两种,group by引起的倾斜和join引起的倾斜。

group by造成的倾斜有两个参数可以解决

  1. 一个是hive.map.aggr,默认值已经为true,意思是会做map端的combiner。所以如果你的group by查询只是做count(*)的话,其实是看不出倾斜效果的,但是如果你做的是count(distinct),那么还是会看出一点倾斜效果。
  2. 另一个参数是hive.groupby.skewindata。这个参数的意思是做reduce操作的时候,拿到的key并不是所有相同值给同一个reduce,而是随机分发,然后reduce做聚合,做完之后再做一轮MR,拿前面聚合过的数据再算结果。所以这个参数其实跟hive.map.aggr做的是类似的事情,只是拿到reduce端来做,而且要额外启动一轮job,所以其实不怎么推荐用,效果不明显。

join引起的倾斜

skew join的流程可以用下图描述:

小文件合并

当Hive输入由很多个小文件组成,由于每个小文件都会启动一个map任务,非常消耗资源,设置参数 set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat 在map处理之前将多个小文件合并。合并文件数由mapred.max.split.size限制的大小决定。

Map阶段的优化

如果一个job大部分时间花在任务处理上,说明名可能是map个数太少了,并行度不高,这时可以考虑增加map个数

直接调整mapred.map.tasks这个参数是没有效果的。

Reduce阶段的优化

主要是设置reduce个数

方法一:

方法二:

索引

hive中的索引是一个比较鸡肋的功能,hive中一般做扫描操作,而索引主要用于精确查找。

索引可以加快group by的速度

推测执行

目的:是通过加快获取单个 task 的结果以及进行侦测将执行慢的 TaskTracker 加入到黑名单的方式来提高整体的任务执行效率

对于需要消耗大量资源的任务不建议推测执行,因为推测执行会让整个系统资源竞争更严重

$HADOOP_HOME/conf/mapred-site.xml 文件

  <property>
  <name>mapred.map.tasks.speculative.execution </name>
  <value>true</value>
  </property>
<property>
  <name>mapred.reduce.tasks.speculative.execution </name>
  <value>true</value>
  </property>
 

数据压缩

set hive.exec.compress.intermediate=true;
# 设置用snappy压缩,hive也有一个默认压缩方法DefaultCodec
set hive.intermediate.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;
set hive.intermediate.compression.type=BLOCK;
set hive.exec.compress.output=true;
set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;
set mapred.output.compression.type=BLOCK:

group by优化

hive.groupby.skewindata=true;

set hive.groupby.mapaggr.checkinterval=100000;

union all优化

优化思想是尽量让job并行