Hive optimization

Analysis and solution of OOM problem when running MapReduce job in Hive

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

 

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

 

hive optimization 1

 

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

 

1. Aggregation optimization

set hive.map.aggr=true;

Penalizes the top-level aggregation process in the map stage, this setting requires more memory.

 

2. Local mode

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

hive will try to perform the operation in local mode

 

3. join optimization

 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';

The same a.ymd after on can put a mapreduce and connect three tables in one mapreduce.

 

b. The small watch is placed in the front, and the large watch is placed in the back.

    Hive will assume that the last table is the largest table and cache the previous tables.

    Of course, it can also be specified intelligently, such as:

   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;

 

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326643745&siteId=291194637