阅读这篇文章后,会对hive 与 map/reduce有基本了解,并掌握简单的优化方法
•一、Hive map reduce个数优化
Map的个数是怎么产生的
主要的决定因素有: input的文件总个数,input的文件大小,集群设置的文件块大小(目前为128M, 可在hive中通过set dfs.block.size;命令查看到,该参数不能自定义修改);
如:
1)假设input目录下有1个文件a,大小为780M,那么hadoop会将该文件a分隔成7个块(6个128m的块和1个12m的块),从而产生7个map数
2)假设input目录下有3个文件a,b,c,大小分别为10m,20m,130m,那么hadoop会分隔成4个块(10m,20m,128m,2m),从而产生4个map数
即,如果文件大于块大小(128m),那么会拆分,如果小于块大小,则把该文件当成一个块。
1.控制map个数
减小map个数:
set mapred.max.split.size=100000000;
set mapred.min.split.size.per.node=100000000;
set mapred.min.split.size.per.rack=100000000;
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
增大map个数:
set mapred.reduce.tasks=10;
create table a_1 as
select * from a
distribute by rand(123);
2.控制reduce个数
reduce个数的设定极大影响任务执行效率,不指定reduce个数的情况下,Hive会猜测确定一个reduce个数,主要基于以下两个设定:
hive.exec.reducers.bytes.per.reducer 默认1G
hive.exec.reducers.max 默认999个
min(总输入数据量/参数1,参数2)
调整方法
1.调整hive.exec.reducers.bytes.per.reducer参数
如 set hive.exec.reducers.bytes.per.reducer=500000000 500M
2.set mapred.reduce.tasks = 15;
3.当然还有很多情况只能用到一个reduce如:
a) 没有group by的汇总
b) 用了Order by
c) 有笛卡尔积总结:根据实际情况,控制map/reduce数量需要遵循两个原则:使大数据量利用合适的map/reduce数;使单个map/reduce任务处理合适的数据量.
•二、列裁剪(Column Pruning)
在读数据的时候,只读取查询中需要用到的列,而忽略其他列。例如,对于查询:
SELECT a,b FROM T WHERE e < 10;其中,T 包含 5 个列 (a,b,c,d,e),列 c,d 将会被忽略,只会读取a, b, e 列
这个选项默认为真: hive.optimize.cp = true
•三、分区裁剪(Partition Pruning)
在查询的过程中减少不必要的分区。例如,对于下列查询:
SELECT * FROM (SELECT c1, COUNT(1)
FROM T GROUP BY c1) subq
WHERE subq.prtn = 100;
SELECT * FROM T1 JOIN
(SELECT * FROM T2) subq ON (T1.c1=subq.c2)
WHERE subq.prtn = 100;
会在子查询中就考虑 subq.prtn = 100 条件,从而减少读入的分区数目。
此选项默认为真:hive.optimize.pruner=true