【发布时间】:2013-11-03 10:18:06
【问题描述】:
我在我的 java 程序中使用conf.setNumMapTasks() 明确指定了映射器的数量,但是当作业结束时,计数器显示启动的映射任务的数量超过了指定的值。如何将mapper的数量限制为指定值?
【问题讨论】:
-
你最近问了很多问题,大部分问题都得到了很好的回答。 SO 礼节说你应该接受每个问题的最佳答案。
我在我的 java 程序中使用conf.setNumMapTasks() 明确指定了映射器的数量,但是当作业结束时,计数器显示启动的映射任务的数量超过了指定的值。如何将mapper的数量限制为指定值?
【问题讨论】:
根据 Hadoop API Jonf.setNumMapTasks 只是对 Hadoop 运行时的提示。 map任务的总数等于输入数据中要处理的块数。
不过,应该可以通过使用 mapred-site.xml 中的 mapred.tasktracker.map.tasks.maximum 和 mapred.tasktracker.reduce.tasks.maximum 来配置每个节点的 map/reduce 槽数。这样就可以配置在整个集群中并行执行的映射器/减速器的总数。
【讨论】:
使用conf.setNumMapTasks(int num),映射器的数量可以增加但不能减少。
您不能将映射器数量显式设置为小于 Hadoop 计算的映射器数量的特定数量。这取决于 hadoop 为您的给定输入集创建的输入拆分数量。你可以通过设置mapred.min.split.size parameter来控制它。
引用wiki页面:
map 的数量通常由 DFS 中的块数驱动 输入文件。虽然这会导致人们调整他们的 DFS 块 大小来调整地图的数量。合适的并行度 地图似乎在 10-100 个地图/节点左右,尽管我们已经使用它 对于非常 cpu-light map 任务,到 300 左右。任务设置需要一段时间,所以 最好是地图至少需要一分钟才能执行。
实际上控制地图的数量是微妙的。这 mapred.map.tasks 参数只是对 InputFormat 的提示 地图数量。默认的 InputFormat 行为是拆分总数 字节数到正确数量的片段中。然而,在 默认情况下,输入文件的 DFS 块大小被视为 输入拆分的上限。拆分大小的下限可以是 通过 mapred.min.split.size 设置。因此,如果您期望 10TB 的输入数据 并且有 128MB DFS 块,你最终会得到 82k 的地图,除非你的 mapred.map.tasks 更大。最终 InputFormat 确定 地图的数量。
地图任务的数量也可以使用手动增加 JobConf 的 conf.setNumMapTasks(int num)。这可以用来增加 地图任务的数量,但不会设置低于 Hadoop 通过拆分输入数据来确定。
【讨论】:
引用JobConf#setNumMapTasks()的javadoc:
注意:这只是对框架的提示。实际人数 生成的地图任务取决于生成的
InputSplits 的数量 工作的InputFormat.getSplits(JobConf, int)。自定义InputFormat是 通常用于精确控制地图任务的数量 工作。
Hadoop 还会重新启动失败或长时间运行的地图任务以提供高可用性。
您可以限制在单个节点上同时运行的映射任务的数量。如果您有大输入文件,您可以限制启动任务的数量。您必须编写自己的 InputFormat 类,该类不可拆分。然后 Hadoop 将为您拥有的每个输入文件运行一个映射任务。
【讨论】:
根据 [Partitioning your job into maps and reduces],如下:
mapred.map.tasks 参数只是对 InputFormat 地图数量的提示。默认的 InputFormat 行为是将总字节数拆分为正确数量的片段。但是,在默认情况下,输入文件的 DFS 块大小被视为输入拆分的上限。可以通过 mapred.min.split.size 设置拆分大小的下限。因此,如果您期望 10TB 的输入数据和 128MB 的 DFS 块,那么您最终会得到 82k 个地图,除非您的 mapred.map.tasks 更大。最终,InputFormat 决定了地图的数量。
不过,您可以了解有关 InputFormat 的更多信息。
【讨论】: