Hive 优化

Hive中跑MapReduce Job出现OOM问题分析及解决

https://blog.csdn.net/oopsoom/article/details/41356251

 

======================================================================================================================================================================================================

 

hive优化1

 

======================================================================================================================================================================================================

 

1.聚合优化

set hive.map.aggr=true;

处罚map阶段顶级聚合过程,这个设置需要更多的内存。

 

2.本地模式

set hive.exec.mode.local.auto=true;

hive会尝试用本地模式执行操作

 

3.join优化

 a.少MapReduce

    select a.ymd,a.price_close,b.price_close,c.price_close

    from stocks a

    join stocks b on a.ymd=b.ymd

    join stocks c on a.ymd=c.ymd

    where a.symbol = 'AAPL' and b.symbol = 'IBM' and c.symbol = 'GE';

on 后面都有相同的a.ymd 可以放一个mapreduce ,在一个mapreduce中连接三张表。

 

b.小表放前面,大表放后面。

    hive会假定最后一个表是最大的表,将前面的表缓存起来。

    当然,也可以智能指定,如:

   select  /*+STREAMTABLE(s) */ s.ymd,s.symbol,s.price_close,d.dividend

   from stock s join dividends d on s.ymd=d.ymd and s.symbol=d.symbol where s.symbol='appl' ;

 

4.LEFT OUTER JOIN优化

 

左连接时,左表中出现的JOIN字段都保留,右表没有连接上的都为空。对于带WHERE条件的JOIN语句,例如:

 

SELECT a.val, b.val FROM a LEFT OUTER JOIN b ON(a.key=b.key)

 

WHERE a.ds='2009-07-07' AND b.ds='2009-07-07'

 

执行顺序是,首先完成2表JOIN,然后再通过WHERE条件进行过滤,这样在JOIN过程中可能会输出大量结果,再对这些结果进行过滤,比较耗时。可以进行优化,将WHERE条件放在ON后,例如:

 

SELECT a.val, b.val FROM a LEFT OUTER JOIN b

 

ON(a.key=b.key AND b.ds='2009-07-07'AND a.ds='2009-07-07')

 

这样,在JOIN的过程中,就对不满足条件的记录进行了预先过滤,可能会有更好的表现。

 

5.Map Side JOIN

 

Map Side JOIN优化的出发点是,Map任务输出后,不需要将数据拷贝到Reducer节点,降低的数据在网络节点之间传输的开销。

多表连接,如果只有一个表比较大,其他表都很小,则JOIN操作会转换成一个只包含Map的Job,例如:

 

SELECT /*+ MAPJOIN(b) */ a.key, a.value FROM a JOIN b ON a.key = b.key

 

对于表a数据的每一个Map,都能够完全读取表b的数据。这里,表a与b不允许执行FULL OUTER JOIN、RIGHT OUTER JOIN。

 

6.并行执行

 

hive的查询会转变成一个或者多个阶段,这样的阶段可以是mapreduce阶段,抽样阶段,合并阶段,limit阶段

或者是hive执行中可能需要的其他阶段。默认情况下,hive只会执行一个阶段,不过某些特定的job会执行多个阶段,而这些阶段有些事没有互相依赖的,这些没有依赖的是可以并行执行的,缩短时间。

 

开发并发执行  set hive.exec.parallel=true;

 

7.jvm重用

?JVM重用是是hadoop调优参数的内容,其对hadoop的性能有非常大的影响,特别对于很难避免小文件的场景或者是task特别多的场景,这类场景大多数执行时间很短,hadoop默认配置通常是使用派生JVM来执行map和reduce任务的,这是jvm启动可能造成很大的开销,尤其是执行的job包含成百上千task任务的情况。JVM重用可以使得JVM实例在同一个job中重新使用了N次。

参数设置  set mapred.job.reuse.jvm.num.tasks=10;

缺点;

开启jvm将会一直占用使用的task插槽,以便进行重用,知道任务完成后才能释放。如果某个不平衡的job中有几个reduce task要比其他的reduce task消耗的时间多的多的话,那么保留的插槽就会一直空闲着却无法被其他的job使用,直到所有的task都结束了才会释放。

 

 

 

 

======================================================================================================================================================================================================

 

hive优化2

 

======================================================================================================================================================================================================

 

1.脚本参数设置

 

1.1 简单列查询不启用mapreduce

 

set hive.fetch.task.conversion=more;

 

 

开启了Fetch任务,所以对于简单的列查询不在启用MapReduce job!

 

例如:SELECT id, money FROM m limit 10;

 

1.2 是否显示表的列名

 

set hive.cli.print.header=true;

 

 

是否显示表的列名。

 

例如:

 

hive> set hive.cli.print.header=true;

hive> select * from t04;

OK

id      name

Time taken: 0.136 seconds

hive> set hive.cli.print.header=false;

hive> select * from t04;

OK

Time taken: 0.08 seconds

 

1.3 设置最大rudece个数

 

set hive.exec.reducers.max=88;

 

最大的reduce的个数为88.

 

1.4 hive输出是否进行压缩

 

 set hive.exec.compress.output=false;

 

 最终结果不压缩

 

 

 

 set hive.exec.compress.intermediate=true;

 

中间结果压缩,决定查询的中间 map/reduce job (中间 stage)的输出是否为压缩格式。

 

 

1.5 合并小文件

 

Set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

 

在执行之前进行小文件合并

 

set mapred.max.split.size=256000000;

 

合并文件最大为256M

 

set mapred.min.split.size.per.node=1;(设置大小不合理)

 

 

set mapred.min.split.size.per.rack=1;(设置大小不合理)

 

 

例如:

 

set mapred.max.split.size=1000;

 

set mapred.min.split.size.per.node=300;

 

 

set mapred.min.split.size.per.rack=100;

 

 

输入目录下五个文件,rack1下三个文件,长度为2050,1499,10, rack2下两个文件,长度为1010,80. 另外blockSize为500.

 

 

经过第一步, 生成五个split: 1000,1000,1000,499,1000. 剩下的碎片为rack1下:50,10; rack2下10:80

 

 

由于两个rack下的碎片和都不超过100, 所以经过第二步, split和碎片都没有变化.

 

 

第三步,合并四个碎片成一个split, 长度为150.

 

 

1.6 MapJoin机制

 

 set hive.ignore.mapjoin.hint=true;

 

 set hive.auto.convert.join = true;

 

 set hive.smalltable.filesize=1000000000;(设置大小不合理)

 

 

开启mapjoin优化机制

 

1.7队列job名

 

set mapred.queue.name=oia;

 

set mapred.job.queue.name=oia;

 

Set mapred.job.name=oia_${pt_month}_${v_proc_name};

 

 

2.其他参数

 

2.1 本地模式

 

set hive.exec.mode.local.auto=true;

 

Hive会自动选择是否用本地模式

 

 

0.7版本后Hive开始支持任务执行选择本地模式(local mode)。大多数的Hadoop job是需要hadoop提供的完整的可扩展性来处理大数据的。不过,有时hive的输入数据量是非常小的。在这种情况下,为查询出发执行任务的时间消耗可能会比实际job的执行时间要多的多。对于大多数这种情况,hive可以通过本地模式在单台机器上处理所有的任务。对于小数据集,执行时间会明显被缩短。

 

 

如此一来,对数据量比较小的操作,就可以在本地执行,这样要比提交任务到集群执行效率要快很多。

 

2.2 数据倾斜

 

Set hive.groupby.skewindata = true;

 

有数据倾斜的时候进行负载均衡

 

 

2.3 并行执行

 

hive的查询会转变成一个或者多个阶段,这样的阶段可以是mapreduce阶段,抽样阶段,合并阶段,limit阶段

 

或者是hive执行中可能需要的其他阶段。默认情况下,hive只会执行一个阶段,不过某些特定的job会执行多个阶段,而这些阶段有些事没有互相依赖的,这些没有依赖的是可以并行执行的,缩短时间。

 

 

开发并发执行  set hive.exec.parallel=true;

 

 

2.4 jvm重用

 

?JVM重用是是hadoop调优参数的内容,其对hadoop的性能有非常大的影响,特别对于很难避免小文件的场景或者是task特别多的场景,这类场景大多数执行时间很短,hadoop默认配置通常是使用派生JVM来执行map和reduce任务的,这是jvm启动可能造成很大的开销,尤其是执行的job包含成百上千task任务的情况。JVM重用可以使得JVM实例在同一个job中重新使用了N次。

 

参数设置  set mapred.job.reuse.jvm.num.tasks=10;

 

缺点:

 

开启jvm将会一直占用使用的task插槽,以便进行重用,知道任务完成后才能释放。如果某个不平衡的job中有几个reduce task要比其他的reduce task消耗的时间多的多的话,那么保留的插槽就会一直空闲着却无法被其他的job使用,直到所有的task都结束了才会释放。

 

 

 

 

3.join优化

 

3.1 执行计划

 

EXPLAIN SELECT SUM(Number) FROM onecol

 

 

可以看一个sql的执行计划,怎么样解析执行的情况。

 

 

3.2 表顺序

 

小表放前面,大表放后面,hive会假定后面的一张表是大表,将前面的缓存起来。

 

 

3.3 LEFT OUTER JOIN优化

 

 

左连接时,左表中出现的JOIN字段都保留,右表没有连接上的都为空。对于带WHERE条件的JOIN语句,例如:

 

 

 

SELECT a.val, b.val FROM a LEFT OUTER JOIN b ON(a.key=b.key)

 

WHERE a.ds='2009-07-07' AND b.ds='2009-07-07'

 

执行顺序是,首先完成2表JOIN,然后再通过WHERE条件进行过滤,这样在JOIN过程中可能会输出大量结果,再对这些结果进行过滤,比较耗时。可以进行优化,将WHERE条件放在ON后,例如:

 

 

SELECT a.val, b.val FROM a LEFT OUTER JOIN b

 

ON(a.key=b.key AND b.ds='2009-07-07'AND a.ds='2009-07-07')

 

这样,在JOIN的过程中,就对不满足条件的记录进行了预先过滤,可能会有更好的表现。

 

 

 

======================================================================================================================================================================================================

 

常用优化参数

 

======================================================================================================================================================================================================

 

set hive.fetch.task.conversion=more;

 

set hive.cli.print.header=true;

 

set hive.exec.reducers.max=88;

 

set hive.exec.compress.output=false;

 

set hive.exec.compress.intermediate=true;

 

set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

 

set mapred.max.split.size=128000000;

 

set mapred.min.split.size.per.node=128000000;

 

set mapred.min.split.size.per.rack=128000000;

 

set hive.ignore.mapjoin.hint=true;

 

set hive.auto.convert.join = true;

 

set hive.smalltable.filesize=25000000;

 

--set mapred.queue.name=oia;

 

--set mapred.job.queue.name=oia;

 

--set mapred.job.name=oia_${pt_month}_${v_proc_name};

 

set hive.exec.mode.local.auto=true;

 

set hive.groupby.skewindata = true;

 

set hive.exec.parallel=true;

 

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

 

 

 

set hive.fetch.task.conversion=more;

set hive.cli.print.header=true;

set hive.exec.reducers.max=88;

set hive.exec.compress.output=false;

set hive.exec.compress.intermediate=true;

set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

set mapred.max.split.size=128000000;

set mapred.min.split.size.per.node=128000000;

set mapred.min.split.size.per.rack=128000000;

set hive.ignore.mapjoin.hint=true;

set hive.auto.convert.join = true;

set hive.smalltable.filesize=25000000;

set hive.exec.mode.local.auto=true;

set hive.groupby.skewindata = true;

set hive.exec.parallel=true;

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

 

 

猜你喜欢

转载自michael-ldd2008.iteye.com/blog/2371013