Hadoop中map与reduce的个数问题

在hadoop中当一个任务没有设置的时候,该任务的执行的map的个数是由任务本身的数据量决定的,具体计算方法会在下文说明;而reduce的个数hadoop是默认设置为1的。为何设置为1那,因为一个任务的输出的文件个数是由reduce的个数来决定的。一般一个任务的结果默认是输出到一个文件中,所以reduce的数目设置为1。那如果我们为了提高任务的执行速度如何对map与reduce的个数来进行调整那。

在讲解之前首先,看一下hadoop官方文档是如何说明的。


Number of Maps
The number of maps is usually driven by the number of DFS blocks in the input files. Although that causes people to adjust their DFS block size to adjust the number of maps. The right level of parallelism for maps seems to be around 10-100 maps/node, although we have taken it up to 300 or so for very cpu-light map tasks. Task setup takes awhile, so it is best if the maps take at least a minute to execute.
Actually controlling the number of maps is subtle. The mapred.map.tasks parameter is just a hint to the InputFormat for the number of maps. The default InputFormat behavior is to split the total number of bytes into the right number of fragments. However, in the default case the DFS block size of the input files is treated as an upper bound for input splits. A lower bound on the split size can be set via mapred.min.split.size. Thus, if you expect10TB of input data and have 128MB DFS blocks, you'll end up with 82k maps(10TB/128MB = 82k), unless your mapred.map.tasks is even larger. Ultimately the InputFormat determines the number of maps.
The number of map tasks can also be increased manually using the JobConf's conf.setNumMapTasks(int num). This can be used to increase the number of map tasks, but will not set the number below that which Hadoop determines via splitting the input data.

Number of Reduces
The right number of reduces seems to be 0.95 or 1.75 * (nodes * mapred.tasktracker.tasks.maximum). At 0.95 all of the reduces can launch immediately and start transfering map outputs as the maps finish. At 1.75 the faster nodes will finish their first round of reduces and launch a second round of reduces doing a much better job of load balancing.
Currently the number of reduces is limited to roughly 1000 by the buffer size for the output files (io.buffer.size * 2 * numReduces << heapSize). This will be fixed at some point, but until it is it provides a pretty firm upper bound.
The number of reduces also controls the number of output files in the output directory, but usually that is not important because the next map/reduce step will split them into even smaller splits for the maps.
The number of reduce tasks can also be increased in the same way as the map tasks, via JobConf's conf.setNumReduceTasks(int num).


上述的说明是map与reduce的个数是如何确定的。对于map的个数是通过任务执行的时候读入的数据量除以每个block的大小(默认是64M)来决定的,而reduce就是默认为1,而且它有个建议范围,这个范围是由你的node个数来决定的。一般reduce的个数是通过:nodes个数 X 一个TaskTracker设置的最大reduce个数(默认为2)  X (0.95~1.75)之间的数目。注意这上述的个数只是设置中的一个最大的上限。在实际运行中的个数,还要看你具体的任务设置。


如果想设置一个任务执行的map与reduce的个数,那可以使用如下方法。

map:当你想更改map的个数的时候,则可以通过更改配置文件中block的size来增大或者减小map的个数,或者通过 JobConf's conf.setNumMapTasks(int num).。但是就算你设置了数目在这里,它在实际运行中的数目不会小于它实际分割产生的数目。意思就是当你通过程序设置map为2个,但是在读入数据的时候,分割数据是需要3个,那么最后任务在实际运行的过程中map个数是3个而不是你设置的2个。

reduce:当想修改reduce的个数那么可以按照如下方法进行更改:

当是在程序调试中可以通过声明一个job对象,调用job.setNumReduceTasks(tasks),或者在conf设置中调用conf.setStrings("mapred.reduce.tasks", values);

而当是通过命令进行执行任务的时候可以在命令行加入运行期参数:

bin/hadoop jar examples.jar  job_name -Dmapred.map.tasks=nums -Dmapred.reduce.tasks=nums INPUT OUTPUT

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Hadoop,Shuffle阶段是指将Mapper节点的输出根据Key值进行分组并发送给Reducer节点,以便Reducer节点进行聚合操作。Shuffle阶段包含三次排序过程,分别是Map端的排序、Partitioner的分区和Reduce端的排序。 1. Map端的排序 在Map端,每个Mapper节点会将自己的输出按照Key进行排序,以便后续的分组和发送操作。这个排序过程是由MapTask内部的MapOutputBuffer实现的,它使用基数排序算法对Key进行排序,同时使用环形缓冲区对排序后的Key进行缓存,以提高效率。 2. Partitioner的分区 在Shuffle阶段,Partitioner的作用是将Mapper节点的输出根据Key值进行分区,以便Reducer节点可以按照分区处理数据。Partitioner的默认实现是HashPartitioner,它使用Key的HashCode对Reducer数量取模,将相同HashCode的Key分配到同一个Reducer节点上。 3. Reduce端的排序 在Reducer节点接收到来自不同Mapper节点的数据后,需要将这些数据按照Key进行排序,以便进行聚合操作。Reducer节点的排序过程是由ReduceTask内部的MergeSort实现的,它对所有Mapper节点的数据进行合并排序,并使用环形缓冲区对排序后的Key进行缓存。在Reduce端的排序过程,还可以通过设置Combiner来进行局部聚合操作,以减少数据传输量和提高效率。 ### 回答2: Hadoop的Shuffle阶段是指在MapReduce任务,在Map阶段结束后,将Mapper输出的键值对进行重新分区、排序和合并的过程。Shuffle阶段共包括三次排序过程,分别为局部排序、分区排序和最终排序。 首先是局部排序,每个Mapper会将输出的键值对按照键进行排序。这是因为可靠的归并操作需要有序的输入,以减少后续的排序和合并开销。在局部排序,每个Mapper的输出键值对会进入一个缓冲区,当缓冲区达到一定大小时,会触发一次排序操作,对缓冲区内的键值对按照键进行排序。 其次是分区排序,Shuffle阶段的主要目标是根据Reduce任务的个数Mapper的输出进行分区,以便后续的Reduce任务能够方便地获取到对应分区的数据。在分区排序,每个Mapper的输出键值对会根据Reducer的个数进行分区,同一个分区内的键值对按照键进行排序。 最后是最终排序,分区排序后的键值对会被发送到相应的Reduce任务进行合并和最终的排序。Hadoop通过将相同键的键值对发送到同一个Reduce任务进行局部聚合,减少了网络传输和排序的开销。在Reduce任务,会继续对属于同一个键的键值对进行排序操作,以得到最终的排序结果。 总的来说,Shuffle阶段的三次排序过程包括局部排序、分区排序和最终排序。局部排序对每个Mapper的输出进行按键排序,分区排序将键值对根据Reducer数量进行分区排序,最终排序进一步对同一键的键值对进行排序合并,得到最终的排序结果。这三次排序过程在Shuffle阶段起到了重要的作用,提高了MapReduce任务的性能和可靠性。 ### 回答3: Shuffle阶段是Hadoop框架的一个关键阶段,负责将Map阶段输出的数据按照key进行排序并传递给Reduce阶段。具体而言,Shuffle阶段包含以下三个排序过程: 1. Map阶段内部的排序:在Map阶段,每个Map任务会将Key-Value对按照key进行排序并分区发送给Reducer。这个排序过程是通过Map任务的内存缓冲区实现的,Map任务将数据按照key存储在内存,并在达到一定大小或者达到一定数量的Key-Value对时将其溢写到磁盘,其采用的是快速排序算法。排序完成后,将进一步分区划分数据,以满足Reduce任务的数量。 2. 网络传输排序:在Map阶段完成后,Hadoop会将Map任务的结果进行合并和排序,然后将数据传输至Reduce任务所在的节点。这个过程包括三个步骤:首先,对于每个Reduce任务,从每个Map任务取出其对应的分区数据,并进行合并;然后,将合并后的数据根据key进行局部排序;最后,将排序后的数据按照Reduce任务的数量进行划分,然后发送给对应的Reduce任务。 3. Reduce阶段的排序:在Reduce节点接收到Shuffle阶段传递过来的数据后,会进行一次全局排序。Reduce任务获取到所有分区的数据后,在内存对key进行排序,这样所有Reduce节点上的数据都按照key有序排列。排序完成后,Reduce任务开始进行合并操作,将具有相同key的Value进行聚合,以减少数据量,并将结果输出。这个合并过程可以使用合并排序或堆排序等算法实现。 以上是HadoopShuffle阶段的三次排序过程。通过这些排序,Hadoop能够有效地将Map阶段输出的数据按照key进行排序,并将相同key的数据传递给对应的Reduce任务进行处理,从而实现分布式计算的并行处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值