转载自:http://blog.sina.com.cn/s/blog_9f48885501017dua.html 谷腾龙的博客
一、
1.
主要的决定因素有: input的文件总个数,input的文件大小,集群设置的文件块大小(目前为128M, 可在hive中通过setdfs.block.size;命令查看到,该参数不能自定义修改);
2.
a)
b)
即,如果文件大于块大小(128m),那么会拆分,如果小于块大小,则把该文件当成一个块。
3.
答案是否定的。如果一个任务有很多小文件(远远小于块大小128m),则每个小文件也会被当做一个块,用一个map任务来完成,
而一个map任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。
而且,同时可执行的map数是受限的。
4.
答案也是不一定。比如有一个127m的文件,正常会用一个map去完成,但这个文件只有一个或者两个小字段,却有几千万的记录,
如果map处理的逻辑比较复杂,用一个map任务去做,肯定也比较耗时。
针对上面的问题3和4,我们需要采取两种方式来解决:即减少map数和增加map数;
如何合并小文件,减少map数?
如何适当的增加map数?
二、
1.
reduce个数的设定极大影响任务执行效率,不指定reduce个数的情况下,Hive会猜测确定一个reduce个数,基于以下两个设定:
hive.exec.reducers.bytes.per.reducer(每个reduce任务处理的数据量,默认为1000^3=1G)
hive.exec.reducers.max(每个任务最大的reduce数,默认为999)
计算reducer数的公式很简单N=min(参数2,总输入数据量/参数1)
即,如果reduce的输入(map的输出)总大小不超过1G,那么只会有一个reduce任务;
如:select pt,count(1) from popt_tbaccountcopy_mes where pt ='2012-07-04' group by pt;
2.
调整hive.exec.reducers.bytes.per.reducer参数的值;
set hive.exec.reducers.bytes.per.reducer=500000000; (500M)
select pt,count(1) from popt_tbaccountcopy_mes where pt ='2012-07-04' group by pt; 这次有20个reduce
3.
set mapred.reduce.tasks = 15;
select pt,count(1) from popt_tbaccountcopy_mes where pt ='2012-07-04' group by pt;这次有15个reduce
4.
同map一样,启动和初始化reduce也会消耗时间和资源;
另外,有多少个reduce,就会有多少个输出文件,如果生成了很多个小文件,那么如果这些小文件作为下一个任务的输入,则也会出现小文件过多的问题;
5.
很多时候你会发现任务中不管数据量多大,不管你有没有设置调整reduce个数的参数,任务中一直都只有一个reduce任务;
其实只有一个reduce任务的情况,除了数据量小于hive.exec.reducers.bytes.per.reducer参数值的情况外,还有以下原因:
a)
这点非常常见,希望大家尽量改写。
b)
c)
通常这些情况下,除了找办法来变通和避免,我暂时没有什么好的办法,因为这些操作都是全局的,所以hadoop不得不用一个reduce去完成;

本文介绍如何通过调整Hive任务中的Map和Reduce数量来优化任务执行效率。包括如何合并小文件减少Map数,如何适当增加Map数,以及如何合理设置Reduce数。
3万+

被折叠的 条评论
为什么被折叠?



