map和reduce个数怎么确定?

本文探讨了Hadoop中MapReduce任务的优化策略,包括合理设置Map和Reduce任务数量的重要性,以及如何根据输入源和集群资源调整任务参数,以达到最佳的并行处理效果。

阅读本文可以带着下面问题:
1.map和reduce的数量过多会导致什么情况?
2.Reduce可以通过什么设置来增加任务个数?
3.一个task的map数量由谁来决定?
4.一个task的reduce数量由谁来决定?


一般情况下,在输入源是文件的时候,一个task的map数量由splitSize来决定的,那么splitSize是由以下几个来决定的
goalSize = totalSize / mapred.map.tasks
inSize = max {mapred.min.split.size, minSplitSize}
splitSize = max (minSize, min(goalSize, dfs.block.size))
一个task的reduce数量,由partition决定。
在输入源是数据库的情况下,比如mysql,对于map的数量需要用户自己指定,比如
jobconf.set(“mapred.map.tasks.nums”,20);
如果数据源是HBase的话,map的数量就是该表对应的region数量。
map和reduce是hadoop的核心功能,hadoop正是通过多个map和reduce的并行运行来实现任务的分布式并行计算,从这个观点来看,如果将map和reduce的数量设置为1,那么用户的任务就没有并行执行,但是map和reduce的数量也不能过多,数量过多虽然可以提高任务并行度,但是太多的map和reduce也会导致整个hadoop框架因为过度的系统资源开销而使任务失败。所以用户在提交map/reduce作业时应该在一个合理的范围内,这样既可以增强系统负载匀衡,也可以降低任务失败的开销。


1 map的数量
map的数量通常是由hadoop集群的DFS块大小确定的,也就是输入文件的总块数,正常的map数量的并行规模大致是每一个Node是10~100个,对于CPU消耗较小的作业可以设置Map数量为300个左右,但是由于hadoop的每一个任务在初始化时需要一定的时间,因此比较合理的情况是每个map执行的时间至少超过1分钟。具体的数据分片是这样的,InputFormat在默认情况下会根据hadoop集群的DFS块大小进行分片,每一个分片会由一个map任务来进行处理,当然用户还是可以通过参数mapred.min.split.size参数在作业提交客户端进行自定义设置。还有一个重要参数就是mapred.map.tasks,这个参数设置的map数量仅仅是一个提示,只有当InputFormat 决定了map任务的个数比mapred.map.tasks值小时才起作用。同样,Map任务的个数也能通过使用JobConf 的conf.setNumMapTasks(int num)方法来手动地设置。这个方法能够用来增加map任务的个数,但是不能设定任务的个数小于Hadoop系统通过分割输入数据得到的值。当然为了提高集群的并发效率,可以设置一个默认的map数量,当用户的map数量较小或者比本身自动分割的值还小时可以使用一个相对交大的默认值,从而提高整体hadoop集群的效率。


2 reduece的数量
reduce在运行时往往需要从相关map端复制数据到reduce节点来处理,因此相比于map任务。reduce节点资源是相对比较缺少的,同时相对运行较慢,正确的reduce任务的个数应该是0.95或者1.75 *(节点数 ×mapred.tasktracker.tasks.maximum参数值)。如果任务数是节点个数的0.95倍,那么所有的reduce任务能够在 map任务的输出传输结束后同时开始运行。如果任务数是节点个数的1.75倍,那么高速的节点会在完成他们第一批reduce任务计算之后开始计算第二批 reduce任务,这样的情况更有利于负载均衡。同时需要注意增加reduce的数量虽然会增加系统的资源开销,但是可以改善负载匀衡,降低任务失败带来的负面影响。同样,Reduce任务也能够与 map任务一样,通过设定JobConf 的conf.setNumReduceTasks(int num)方法来增加任务个数。


3 reduce数量为0
有些作业不需要进行归约进行处理,那么就可以设置reduce的数量为0来进行处理,这种情况下用户的作业运行速度相对较高,map的输出会直接写入到 SetOutputPath(path)设置的输出目录,而不是作为中间结果写到本地。同时Hadoop框架在写入文件系统前并不对之进行排序。

转自:http://www.aboutyun.com/thread-6945-1-1.html

### 合理设置 Hive 中 Map Reduce 数的最佳实践 在 Hive 中,合理设置 Map Reduce 的数量对于任务性能至关重要。以下是关于如何根据数据量集群资源进行优化的具体说明: #### 1. **Map 数的设置** Map 数的主要决定因素包括输入文件的数量、大小以及集群中块的大小。以下是一些关键点: - 输入文件的总个数会影响 Map 数。如果存在大量小文件(远小于 HDFS 块大小,默认为 128MB),每个小文件会被当作一个单独的任务分配给一个 Map[^5]。 - 如果一个小文件占用一个 Map 任务,而其处理时间较短,则会造成大量的启动开销资源浪费。因此,在这种情况下应考虑合并小文件。 ##### 解决方案:减少 Map 数 为了减少因小文件过多而导致的低效问题,可以启用 Hive 提供的小文件合并功能: ```sql SET hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; SET hive.exec.reducers.bytes.per.reducer=<目标值>; ``` 这将允许多个小文件被组合到同一个 Map 任务中。 ##### 解决方案:增加 Map 数 当输入文件较大且任务逻辑复杂时,可以通过调整 `mapreduce.input.fileinputformat.split.maxsize` 参数来控制每个 Split 的最大尺寸,进而增加 Map 数。例如: ```sql SET mapreduce.input.fileinputformat.split.maxsize=67108864; -- 设置为 64MB ``` 这样可以让更多的 Map 并行运行,从而加速任务执行[^5]。 --- #### 2. **Reduce 数的设置** 合理的 Reduce 数取决于以下几个方面: - 默认情况下,每个 Reduce 处理的数据量由参数 `hive.exec.reducers.bytes.per.reducer` 控制,默认值为 256MB[^3]。 - 单个任务的最大 Reduce 数由参数 `hive.exec.reducers.max` 定义,默认为 1009。 ##### 计算公式 计算 Reduce 数的通用公式如下: \[ \text{N} = \min(\text{hive.exec.reducers.max}, \frac{\text{总输入数据量}}{\text{hive.exec.reducers.bytes.per.reducer}}) \] 其中: - 总输入数据量是指参与运算的所有数据总量; - `hive.exec.reducers.bytes.per.reducer` 表示每个 Reduce 应处理的理想数据量。 ##### 实际操作案例 假设总输入数据量为 1GB(约 \(10^9\) 字节),则可以根据上述公式得出: \[ \text{N} = \min(1009, \frac{10^9}{256 * 10^6}) = \min(1009, 4) = 4 \] 此时会生成 4 个 Reduce 任务。 ##### 动态设置 Reduce 数 也可以通过手动设置 `set mapreduce.job.reduces=N` 来覆盖默认行为。不过这种方式不推荐频繁使用,因为动态调整可能导致资源配置不合理[^2]。 --- #### 3. **注意事项** - **过少的 Reduce 数**:会导致单个 Reduce 负载过高,延长任务完成时间。 - **过多的 Reduce 数**:虽然能加快某些阶段的速度,但会产生额外的初始化成本,并可能引发下游任务中小文件过多的问题[^5]。 - 对于简单的聚合查询(无 Group By 或 Order By),尽量避免不必要的 Reduce 阶段。例如,将带 Group By 的语句重写为更高效的版本。 --- ### 示例代码 以下是一个完整的配置实例,展示如何针对不同场景调整 Map Reduce 参数: ```sql -- 减少小文件带来的影响 SET hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; -- 设置每个 Reduce 处理的数据量为 128MB SET hive.exec.reducers.bytes.per.reducer=134217728; -- 设定最大 Reduce 数为 500 SET hive.exec.reducers.max=500; -- 测试查询 SELECT COUNT(*) FROM large_table WHERE condition='value'; ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值