我正在管理一个由多个用户共享的Hadoop集群。我们经常以极慢的映射器运行作业。例如,我们可能有一个32 GB的句子文件(每行一个句子),我们想要NLP解析(每个句子需要100毫秒)。如果块大小为128 MB,则为250个映射器。这填补了我们相当小的集群(每个节点12个映射器的9个节点是108个映射器),但每个映射器需要很长时间才能完成(小时)。
问题是如果群集为空并且启动了这样的作业,它将使用群集上的所有映射器。然后,如果其他人想要执行一份简短的工作,它会被阻止几个小时。我知道更新版本的Hadoop支持Fair Scheduler中的抢占(我们使用的是Capacity Scheduler),但是新版本也不稳定(我正在焦急地等待下一个版本)。
曾经有specifying the number of mappers的选项,但现在JobConf已被弃用(奇怪的是,它是not deprecated in 0.20.205)。这样可以缓解这个问题,因为使用更多的映射器,每个映射任务都可以在较小的数据集上工作,从而更快地完成。
在0.20.203中有没有解决这个问题的方法?我是否需要继承我的InputFormat(在本例中为TextInputFormat)?如果是这样,我究竟需要指定什么?
答案 0 :(得分:1)
我相信你应该能够增加这些文件的块大小:如果你这样做,那么,自然,你的应用程序将使用更少的映射器。
还要记住作业配置中有map.input.length参数。这会增加分割,因此您可以有效地减少具有较大输入的映射器。
答案 1 :(得分:1)
如果缺少实际物理资源(即群集中的计算机),则更多映射器无法解决您的问题。我会尝试将数据打包在较少的输入文件中,以避免随机硬盘搜索。
编辑:如果您想要更多地图处理器,请尝试将数据划分为多个小文件或减小块大小。
答案 2 :(得分:1)
不确定更多地图制作者是否能解决您的问题。 JobConf#setNumMapTasks对每个作业生成的地图任务上的#没有影响。即使是文件也说这只是对框架的暗示。生成的映射任务数等于作业的输入拆分数。以下是减少InputSplit大小的不同选项,从而增加了InputSplits的数量并增加了map任务的数量。
通过更改dfs.blocksize
来减小HDFS块的大小。但是,这会增加NameNode的负载,因为它必须保留更多的文件与块映射,并且DataBlock报告的大小也会增加。此外,hadoop fs -D fs.local.block.size=134217728 -put local_name remote_location
将更改放入HDFS的新文件的块大小,旧文件将保持原样。旧文件必须从HDFS中取出并以所需的块大小放回。
使用NLineInputFormat控制每张地图的输入行数。为此,必须改变工作。默认为1的mapred.line.input.format.linespermap
必须定义。
从0.21发布mapreduce.input.fileinputformat.split.minsize
和mapreduce.input.fileinputformat.split.maxsize
已定义,但它与新的MR API一起使用。 InputSplit计算在客户端上完成,因此无法对作业客户端强制执行。
计算InputSplit大小的逻辑如下。
protected long computeSplitSize(long blockSize, long minSize, long maxSize) {
return Math.max(minSize, Math.min(maxSize, blockSize));
}
答案 3 :(得分:0)
您无需升级Hadoop即可更改计划程序。我已成功将默认调度程序更改为公平调度程序。只需按照http://hadoop.apache.org/common/docs/r0.20.2/fair_scheduler.html
上的说明操作即可