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;

hive统计parquet表报错

https://blog.csdn.net/lhxsir/article/details/83789102

parquet列式存储格式,所以优先统计某一列:

SELECT count(salesorder_id) FROM tt_sales_order;

相关推荐