Hive调优
使用EXPLAIN
在查询语句前加上EXPLAIN关键字,查询下查询计划和其他一些信息,查询本身不会执行
EXPLAIN EXTENDED
产生更多的输出信息
调整限制
LIMIT需要执行整个查询语句,然后再返回部分结果,通常浪费资源,尽可能避免。
当使用LIMIT语句时,对源数据进行抽样:
<property>
<name>hive.limit.optimize.enable</name>
<value>true</value>
</property>
<property>
<name>hive.limit.row.max.size</name>
<value>100000</value>
</property>
<property>
<name>hive.limit.optimize.limit.file</name>
<value>10</value>
</property>
本地模式
set hive.exec.mode.local.auto=true
并行执行
某个特定的job可能包含众多的阶段,而这些阶段可能并非完全互相依赖
<property>
<name>hive.exec.parallel</name>
<value>true</value>
</property>
严格模式
hive.mapred.mode=strict 禁止3中类型查询
1.分区表,除非WHERE语句含有分区字段过滤条件来限制数据范围
2.使用ORDER BY语句的查询,要求必须使用LIMIT语句
3.笛卡尔积查询(用户期望在执行JOIN查询的时候不适用ON语句而是使用WHERE语句)
调整mapper和reducer个数
确定最佳的mapper个数和reducer个数取决于多个变量,如输入的数据量大小以及对这些数据执行的操作类型
保持平衡性是有必要的:
如果有太多的mapper或reducer任务,导致启动阶段、调度、运行job过程中产生过多的开销;
如果设置的数量太少,那么可能没有充分利用好集群内在的并行性
Hive是按照输入的数据量大小来确定reducer个数的,通过hadoop dfs -count 来计算输入量的大小hive.exec.reducers.bytes.per.reducer默认值为1GB(1024000000)
默认值通常情况下比较合适,不过,有些情况下查询的map阶段会产生比实际输入数据量要多得多的数据;
如果map阶段产生的数据量非常多,根据输入的数据量大小来确定的reducer个数就显得有些少了。
mapred.reduce.tasks默认值为3
hive.exec.reducers.max (集群总Reduce槽位个数*1.5) / (执行中的查询的平均个数)
其中1.5倍数是一个经验系数,用于防止未充分利用集群的情况
JVM重用
可以使得JVM实例在同一个job中重新使用N次,N的值可以在Hadoop的mapred-site.xml中设置
<property>
<name>mapred.job.reuse.jvm.num.tasks</name>
<value>10</value>
</property>
缺点:一直占用使用到的task插槽,以便进行重用,直到任务完成后才释放动态分区调整
配置限制动态分区插入允许创建的分区数在1000个左右,太多的分区对表来说并不好,不过,通常还是将这个值设置的更大以便这些查询执行
hive-site.xml配置文件中设置动态分区模式为严格模式(strict),开启严格模式,必须保证至少有一个分区是静态的
<property>
<name>hive.exec.dynamic.partition.mode</name>
<value>strict</value>
</property>
然后增加一些相关的属性信息,限制查询可以创建的最大动态分区个数
<property>
<name>hive.exec.max.dynamic.partitions</name>
<value>300000</value>
</property>
<property>
<name>hive.exec.max.dynamic.partitions.pernode</name>
<value>10000</value>
</property>
控制DataNode上一次可以打开的文件的个数,必须设置在DataNode的$HADOOP_HOME/conf/hdfs-site.xml配置文件中<property>
<name>dfs.datanode.max.xcievers</name>
<value>8192</value>
</property>
推测执行
触发执行一些重复的任务,加快获取单个task的结果以及进行侦测将执行慢的TaskTracker加入到黑名单方式提高整体的任务执行效率
如果输入数据量很大而需要执行长时间的map或者reduce task的话,那么启动推测执行造成的浪费非常巨大
$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>
//hive本身也可以控制reduce-side的推测执行
<property>
<name>hive.mapred.reduce.tasks.speculative.execution</name>
<value>true</value>
</property>
单个MapReduce中多个GROUP BY
将多个GROUP BY 操作组装到单个MapReduce任务中
<property>
<name>hive.multigroupby.singlemr</name>
<value>false</value>
</property>
虚拟列
1.用于将要进行划分的输入文件名
2.用于文件中块内偏移量
set hive.exec.rowoffset=true;
3.提供了文件的行偏移量
<property>
<name>hive.exec.rowoffset</name>
<value>true</value>
</property>