1

我正在管理一个在多个用户之间共享的 Hadoop 集群。我们经常使用极其缓慢的映射器运行作业。例如,我们可能有一个 32 GB 的句子文件(每行一个句子),我们想要 NLP 解析(每个句子需要 100 毫秒)。如果块大小为 128 MB,则为 250 个映射器。这填满了我们相当小的集群(每个节点 9 个节点乘以 12 个映射器是 108 个映射器),但每个映射器需要很长时间才能完成(小时)。

问题是,如果集群是空的并且启动了这样的作业,它会使用集群上的所有映射器。然后,如果其他人想要做一个短期工作,它会被阻止几个小时。我知道新版本的 Hadoop 支持公平调度器中的抢占(我们使用的是容量调度器),但新版本也不稳定(我焦急地等待下一个版本)。

曾经有指定映射器数量的选项,但现在JobConf已被弃用(奇怪的是,它在 0.20.205 中没有被弃用)。这将缓解这个问题,因为有了更多的映射器,每个映射任务将在更小的数据集上工作,从而更快地完成。

在 0.20.203 中有没有办法解决这个问题?我是否需要子类化我的 InputFormat(在本例中为 TextInputFormat)?如果是这样,我究竟需要指定什么?

4

4 回答 4

1

我相信您应该能够增加这些文件的块大小:如果您这样做,那么您的应用程序自然会使用更少的映射器。

还要记住,作业配置中有 map.input.length 参数。这将增加拆分,因此您实际上拥有更少的映射器和更大的输入。

于 2011-11-16T18:01:13.017 回答
1

如果缺少实际的物理资源(即集群中的机器),更多的映射器将无法解决您的问题。我会尝试将我的数据打包在更少的输入文件中,以避免随机搜索硬盘。

编辑:好的,如果您想要更多映射器,然后尝试将您的数据划分为几个小文件或减小块大小。

于 2011-11-16T18:32:23.220 回答
1

不确定是否有更多的映射器会解决您的问题。JobConf#setNumMapTasks对每个作业产生的地图任务的 # 没有影响。甚至文档也说这只是对框架的提示。生成的地图任务数等于作业的输入拆分数。以下是减小 InputSplit 大小从而增加 InputSplits 数和增加 map 任务数的不同选项。

  • 通过更改来减小 HDFS 块的大小dfs.blocksize。但是,这会增加 NameNode 上的负载,因为它必须保留更多的文件与块映射,并且 DataBlock 报告的大小也会增加。此外,hadoop fs -D fs.local.block.size=134217728 -put local_name remote_location将更改放入 HDFS 中的新文件的块大小,旧文件将保持原样。旧文件必须从 HDFS 中拉出并以所需的块大小放回。

  • 使用NLineInputFormat控制每个地图的输入行数。为此,工作必须改变。mapred.line.input.format.linespermap必须定义默认为 1 的值。

  • 从 0.21 版本开始mapreduce.input.fileinputformat.split.minsizemapreduce.input.fileinputformat.split.maxsize已定义,但它与新的 MR API 一起使用。InputSplit 计算是在客户端上完成的,因此不能对 Job 客户端强制执行。

计算 InputSplit 大小的逻辑如下。

protected long computeSplitSize(long blockSize, long minSize, long maxSize) {  
    return Math.max(minSize, Math.min(maxSize, blockSize));  
}
于 2011-11-17T04:55:52.163 回答
0

您无需升级 Hadoop 即可更改调度程序。我已经成功地将默认调度程序更改为公平调度程序。只需按照http://hadoop.apache.org/common/docs/r0.20.2/fair_scheduler.html上的说明进行操作

于 2011-12-28T19:00:40.973 回答