MapReduce如何设置map的数量和大小

Hadoop MapReduce:理解并设置Map任务数量
本文详细介绍了Hadoop MapReduce中map任务数量的计算方法,包括默认设置、期望大小、处理文件大小的设定以及最终map任务数量的确定。关键参数如mapred.map.tasks、mapred.min.split.size等影响map任务的数量。建议根据输入文件大小和数量调整相关参数以优化任务执行效率。此外,还提供了不同场景下设置map任务数量的简单方法。

1. map数目的计算方法
hadoop提供了一个设置map个数的参数mapred.map.tasks,我们可以通过这个参数来控制map的个数。但是通过这种方式设置map的个数,并不是每次都有效的。原因是mapred.map.tasks只是一个hadoop的参考数值,最终map的个数,还取决于其他的因素。

为了方便介绍,先来看几个名词:
block_size : hdfs的文件块大小,可以通过参数dfs.block.size设置
total_size : 输入文件整体的大小
input_file_num : 输入文件的个数

上述参数都在Hadoop的conf文件中设置了,使用时可以在自己写的脚本上更改这些参数。

(1)默认map个数
如果不进行任何设置,默认的map个数是和blcok_size相关的。

default_num = total_size / block_size;
1
(2)期望大小
可以通过参数mapred.map.tasks来设置程序员期望的map个数,但是这个个数只有在大于default_num的时候,才会生效。

goal_num = mapred.map.tasks;
1
(3)设置处理的文件大小
可以通过mapred.min.split.size 设置每个task处理的文件大小,但是这个大小只有在大于block_size的时候才会生效。

split_size = max(mapred.min.split.size, block_size);
split_num = total_size / split_size;
1
2
(4)计算的map个数

compute_map_num = min(split_num, max(default_num, goal_num))
1
除了这些配置以外,mapreduce还要遵循一些原则。 mapreduce的每一个map处理的数据是不能跨越文件的,也就是说max_map_num <= input_file_num。 所以,最终的map个数应该为:
final_map_num = min(compute_map_num, input_file_num)
经过以上的分析,在设置map个数的时候,可以简单的总结为以下几点:
(1)如果想增加map个数,则设置mapred.map.tasks 为一个较大的值。
(2)如果想减小map个数,则设置mapred.min.split.size 为一个较大的值。
(3)如果输入中有很多小文件,依然想减少map个数,则需要将小文件merger为大文件,然后使用

2. 简单方式设置想要的map个数
控制Task数及Split大小的相关参数

mapred.map.tasks.x
mapred.min.split.size
abaci.split.optimize.enable
1
2
3
Notes:输入目录文件支持分隔,例如gz压缩问题不支持split。

需求1:
File/Seqence等非Combine的InputFormat
单个Split的大小,尽量在1G( > blkSize,默认256M)

mapred.min.split.size=1073741824    // 1024*1024*1024 = 1,073,741,824
1
如果单文件Size小于1G,SplitSize = 文件大小,不是1G

需求2:
File/Seq等非Combine的InputFormat
单个Split的大小,尽量在30M( < blkSize,默认256M)

abaci.split.optimize.enable=false
mapred.map.tasks= ${总数据量}/30M
1
2
需求3:
File/Seq等非Combine的InputFormat
MapTask数固定为m

abaci.split.optimize.enable=false
mapred.map.tasks=m
1
2
需求4:
CombineInputFormat
单Split(Task)处理不超过1G数据

mapred.max.split.size=1073741824 // 1024*1024*1024 = 1,073,741,824
1
3.注意
第2节的方法实际上是将第一节中的split_num给关闭了,计算最终的map个数时只需要计算:

compute_map_num = max(default_num, goal_num)
1
所以在设置mapred.map.tasks时一定要比default_num大才有效。

<think>首先,用户的问题是:"我想查找程序中设置map数量的方法 请问程序中设置map数量的方法"。他们提供了几个引用,我需要参考这些引用来回答。 引用内容总结: - [^1]: 提到了设置map个数的方法:增加map个数设置mapred.map.tasks;减少map个数设置mapred.min.split.size;处理小文件时合并文件。 - [^2]: 指出mapred.map.tasks只是参考值,实际map数还取决于其他因素。 - [^3]: 讨论了mapreduce数量设置,提到最后一个文件的处理机制。 - [^4]: 在HIVE上下文中讨论mapreduce数量,提到小文件问题及优化。 - [^5]: 解释了map任务数量设定原则,包括map不能跨文件,min_map_num >= input_file_num。 用户明确指出:"上述引用仅供参考,并不是用户真正的需求",所以我应该基于用户的问题核心来回答:"程序中设置map数量的方法"。 用户上一次的问题是我的初始提示,不是一个交互历史。在我的系统指令中,它说:"参考用户上一次的问题你的回答",但在这个对话中,用户只有这一次查询。所以,我专注于当前问题。 关键点:"程序中设置map数量的方法",意思是在代码中如何设置map数量。 从引用中提取相关信息: - 引用[1][2]提到可以通过设置参数如mapred.map.tasks来控制map数量。 - 引用[2]强调mapred.map.tasks不是总是有效的,因为其他因素影响。 - 其他引用涉及优化处理小文件。 所以,在程序中设置map数量的具体方法是通过配置参数。 在Hadoop MapReduce中,设置map数量的参数是: - mapred.map.tasks 或 mapreduce.job.maps(在新API中) 但如引用[2]所说,这不是硬性限制,实际map数取决于输入分片的数量。 输入分片由InputFormat决定,通常是FileInputFormat,它基于文件大小大小。 用户提到了"程序中",意思是代码中如何设置。 在Java程序中设置MapReduce作业时,可以通过Job对象设置配置属性。 例如: ```java Configuration conf = new Configuration(); conf.set("mapred.map.tasks", "10"); // 设置map任务数为10 Job job = Job.getInstance(conf, "my job"); // 其他设置... ``` 或者使用新API: ```java job.setNumMapTasks(10); // 这在新API中可能不直接支持,需要设置配置 ``` 在现代Hadoop API中,建议使用mapreduce.job.maps。 引用[5]提到map数不能小于输入文件数,因为每个文件至少有一个map。 还要考虑小文件问题,如引用[4]所述,小文件过多会导致map数过多。 回答结构: 1. **介绍方法**:解释如何在程序中设置map数量。 2. **核心参数**:指定参数如mapred.map.tasks或mapreduce.job.maps。 3. **注意事项**:强调这不是绝对的,实际map数取决于输入数据集群配置。 4. **示例**:提供代码示例。 5. **相关问题**:生成相关问题,作为系统指令的一部分。 系统指令要求: - 使用中文回答。 - 行内数学表达式用$...$,但这里可能没有数学内容,所以可能不需要。 - 独立公式用$$...$$,如果有。 - LaTeX语法正确:可能不适用。 - 生成相关问题:在末尾。 - 引用标识:如果引用参考,添加[^n]。 用户提供的引用是参考,我可以引用它们。 回答组织: - 开头直接回答问题。 - 解释设置方法。 - 讨论影响因素。 - 提供代码片段。 - 结束相关问题。 相关问题生成:基于主题,如优化map数量、处理小文件等。 最终输出格式: - 中文。 - 清晰结构。 </think>### 程序中设置Map数量的方法 在Hadoop MapReduce或相关框架(如Apache Spark、HIVE)中,设置Map任务数量的方法主要通过配置参数实现。以下是基于引用内容MapReduce工作机制的详细说明。注意:实际Map数量并不完全由程序设置决定,因为Hadoop会根据输入数据大小、文件数量、块大小(默认128MB)等因素动态调整[^2][^5]。设置参数仅作为参考值,目的是优化性能或满足特定需求。 #### 核心设置方法 在程序中(例如Java、Python或配置文件中),您可以通过以下参数控制Map数量: 1. **设置参数 `mapred.map.tasks`(旧API)或 `mapreduce.job.maps`(新API)**: 这是最直接的方法。在作业配置中,指定一个期望的Map任务数。但实际数量可能因输入数据而被覆盖(例如,输入文件数或块大小优先)[^1][^2]。 **Java示例(使用Hadoop MapReduce API)**: ```java import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.mapreduce.Job; public class MapCountExample { public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); // 设置期望的Map任务数为10(新API推荐使用mapreduce.job.maps) conf.setInt("mapreduce.job.maps", 10); // 或使用旧参数: conf.set("mapred.map.tasks", "10"); Job job = Job.getInstance(conf, "My MapReduce Job"); // 其他作业设置(如输入输出路径、Mapper/Reducer类等) job.waitForCompletion(true); } } ``` **说明**: - 此参数仅建议一个目标值。如果输入文件较少或数据量小,实际Map数量可能低于设置值(例如,一个129MB文件可能只生成1个Map任务,以避免碎片化)[^3]。 - 在新版Hadoop(YARN之后),优先使用 `mapreduce.job.maps`。 2. **间接控制:通过输入分片大小** 如果您想减少Map数量,可以增大每个Map处理的数据量(分片大小),这会覆盖参数设置[^1][^5]。关键参数是 `mapred.min.split.size`(最小分片大小)。 **Java示例**: ```java conf.set("mapred.min.split.size", "134217728"); // 设置为128MB(单位字节),以减少Map数量 ``` - 增大此值会合并小分片,从而减少Map任务数(例如,多个小文件可能被合并到一个Map中)[^1][^4]。 - 注意:Map数量不能小于输入文件数,因为每个文件至少对应一个Map任务(除非文件合并)[^5]。 3. **处理小文件场景**: 如果输入包含许多小文件(如HIVE中的分区表生成数千个小文件),直接设置参数可能无效。此时需要先在程序中合并文件: - 在MapReduce作业前添加预处理步骤(如使用 `CombineFileInputFormat`)。 - HIVE中,可以启用小文件合并机制(例如,设置 `hive.merge.mapfiles=true`),再结合参数调整[^4]。 #### 注意事项 - **实际影响因素**:最终Map数量由以下公式决定(基于引用[^5]): $$ \text{实际 Map 数量} = \max(\text{输入文件数}, \left\lceil \frac{\text{总输入大小}}{\text{分片大小}} \right\rceil) $$ 其中分片大小受 `mapred.min.split.size` `mapred.max.split.size` 限制。程序设置只是“建议”值。 - **为什么设置不总是有效**:Hadoop优先考虑数据本地性输入分片。如果参数设置值不合理(如设得过大导致资源浪费),集群可能忽略它[^2][^3]。 - **优化建议**: - 增加Map数量:适用于大文件或高并发需求,但需避免过多Map导致开销增加。 - 减少Map数量:适用于小文件场景,通过合并文件或增大分片大小来提升效率[^1][^4]。 #### 总结 在程序中设置Map数量的主要方法是配置 `mapreduce.job.maps` 或 `mapred.map.tasks` 参数,但实际数量受输入数据约束。推荐结合文件合并(针对小文件)来确保设置生效。如果您的场景涉及HIVE或其他框架,参数名可能略有不同(如HIVE使用 `hive.exec.reducers.bytes.per.reducer` 间接影响Map)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值