彻底明白Hadoop map和reduce的个数决定因素

Hadoop map和reduce的个数设置,困扰了很多学习Hadoop的成员,为什么设置了配置参数就是不生效那?Hadoop Map和Reduce个数,到底跟什么有关系。首先他的参数很多,而且可能随着版本不同一些配置参数,会发生一些变化,但是只要我们搞懂核心问题,那么其它在变,我们都能确定map的个数和reduce的个数。


首先来说,我们通过配置,无论你说的什么配置,能否就设置几个,就会跑出来几个。可以明确的如果设置几个,就有几个,那肯定是瞎猫捧着死耗子了。如果不懂原理,永远不能掌控Map和reduce的个数。

那么map和reduce的个数决定因素是什么?
map个数的决定因素是分片(Split)
reduce个数的决定因素是分区函数

1.map个数的决定因素是Split
如果你不懂Split,和分区函数,这里在跟大家白话以下:
Split在这里是一个名词,它跟map是什么关系?
Split:Map=1:1
它们之间是一一对应的。

整理了一份适合2018年学习的大数据资料需要的加群QQ群:834325294 注明优快云既可免费获取
那么为什么会产生Split?
在大量的数据面前,我们不在适用单台机器,而是使用多台机器共同完成任务,既然多台完成,那么数据该怎么劈开?
ok,Split吧,对的,这里的Split是个动词,不再是一个名词,我们劈开之后那?每一个被劈开的数据,我们都交给map来处理。所以我们现在是否明白,map和split为什么是1:1的关系了。

上面我们只是白话了,那么这里面其实这里面还有一些问题,那么就是该如何Split?
比如1G的数据,该多少位一个块,或则多少M一个Split。这里面又有学问了,或则说又有门道了,因为不能直接设置,所以很多人对这个有迷惑了,直接设置不就好了。Hadoop可能怕我们胡乱设置,所以采取了一个折中的办法?那么它是如何做的?
SplitSize分片大小= min(minSize, max(blockSize, maxSize)) 

看上面公式,我们看到这个SplitSize的大小是折中的,也就是在minSize,blockSize,maxSize中,只取中间值,不取最大的,也不取最小的。我们分解开来如下:
当mapreduce.input.fileinputformat.split.maxsize > mapreduce.input.fileinputformat.split.minsize > dfs.blockSize的情况下,此时的splitSize 将由mapreduce.input.fileinputformat.split.minsize参数决定

当mapreduce.input.fileinputformat.split.maxsize > dfs.blockSize > mapreduce.input.fileinputformat.split.minsize的情况下,此时的splitSize 将由dfs.blockSize配置决定

当dfs.blockSize > mapreduce.input.fileinputformat.split.maxsize > mapreduce.input.fileinputformat.split.minsize的情况下,此时的splitSize将由mapreduce.input.fileinputformat.split.maxsize参数决定。


那么这时候,你是否明白,map的个数跟什么有关系了?
也就是说我们设置的map个数,如何我们不懂上面的原理,肯定是不会生效的。这就是我们为什么要优化的集群的原因了。

2.reduce个数的决定因素是分区函数
reduce我们知道有一个参数setNumReduceTasks(int num),为什么设置之后不生效那?
对于分区函数?肯定是没有理解的。分区函数,在这里我们叫它分类函数,更贴近我们的生活。
这里举我们生活中的例子:

我们生活中,除了男就是女,所以分区函数如下

 

这里应该是有两个reduce的,可是我们设置为setNumReduceTasks为3,这是不可能有3个reduce,即使说是我们Hadoop产生了3个reduce,那么也是有一个reduce是不干活的。所以你设置了3个,可能只看到2个reduce在跑。

比如我们中国有23个省,那么就有23个reduce,你硬设置是24个reduce。这显然是不合理的。

当然还有另外一种特殊的情况下会生效,那就是设置reduce的个数为1,我们会看到只有1个reduce运行。

3.总结
从上面我们就可以明白map和reduce我们为什么设置参数为什么没有生效,以及我们该如何设置合适的参数。有问题欢迎交流。

 

在Hive中合理控制mapreduce个数,可从以下方面着手: ### 控制Hive任务中的map数 - **合并小文件减少map数**:并非文件超过128m就一定会被拆分,且map数并非越多越好。可以通过合并小文件的方式减少map数,避免过多小文件导致过多map任务,降低性能。例如将多个小文件合并成一个较大的文件,保证每个map处理接近128m的文件块,但这也并非绝对安全,还需根据实际情况调整[^1]。 - **适当增加map数**:在某些情况下,需要适当增加map数。不过要综合考虑数据分布、集群资源等因素,以达到最佳性能[^1]。 ### 控制Hive任务的reduce数 - **设置每个reduce处理数据量**:默认每个reduce处理数据量为1G,可通过设置`hive.exec.reducers.bytes.per.reducer`参数来调整。例如设置为500M: ```sql set hive.exec.reducers.bytes.per.reducer=500000000; ``` 若map端输出的总大小是9G,默认每个reduce处理256MB数据时,reducer数量就是9000/256 = 35;当调大`hive.exec.reducers.bytes.per.reducer`到500M时,reducer数目就是18个[^2][^3]。 - **直接调整reduce个数**:可使用`mapred.reduce.tasks`或`mapreduce.job.reduces`参数直接设置reduce个数。例如设置为15个: ```sql set mapred.reduce.tasks = 15; ``` 或在hadoop的`mapred-default.xml`文件中修改: ```sql set mapreduce.job.reduces = 15; ``` - **计算reducer数的公式**:涉及两个参数,每个Reduce处理的数据量(默认256MB,即`hive.exec.reducers.bytes.per.reducer=256000000`)每个任务最大的reduce数(默认为1009,即`hive.exec.reducers.max=1009`)。reducer数N的计算公式为:$N = min(参数2,总输入数据量 / 参数1)$ [^4]。 - **只有一个reduce的情况**:在没有group by的汇总(如`select pt,count(1) from tablea group by pt;`去掉`group by`)、使用了`Order by`或有笛卡尔积的情况下,通常只有一个reduce[^2]。 ### 其他考虑因素 当输出文件的平均大小小于`hive.merge.smallfiles.avgsize`的值时,会启动一个独立的map - reduce任务进行文件merge,可通过以下设置: ```sql SET hive.merge.smallfiles.avgsize = 16777216; ``` 同时,reduce个数并非越多越好,过多的启动初始化reduce会消耗时间资源,且会生成较多输出文件,若这些小文件作为下一个任务的输入,会出现小文件过多的问题[^4]。
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值