我在Hadoop平台(cloudera发行版)上编写了一个相对简单的map-reduce程序。每张地图除了常规的map-reduce任务外,还将一些诊断信息写入标准输出。
然而,当我查看这些日志文件时,我发现Map任务相对均匀地分布在节点之间(我有8个节点)。但是,reduce任务标准输出日志只能在一台机器中找到。
我猜,这意味着所有的reduce任务最终在一台机器上执行,这是有问题的,令人困惑的。
有人知道这里发生了什么吗?是配置问题吗?我怎样才能使减少的工作也平均分配?
如果所有映射器的输出都具有相同的键,它们将被放入单个reducer中。
如果你的作业有多个reducer,但是它们都在一台机器上排队,那么你就有一个配置问题。
使用web界面(http://MACHINE_NAME:50030
)来监视作业,并查看它所具有的减速器以及正在运行它们的机器。还有其他信息可以深入研究,这些信息应该有助于解决问题。
关于配置的几个问题:
- 有多少个reducer正在为这个作业运行?
- 每个节点上有多少个reducer可用?
- 运行减速机的节点更好硬件比其他节点好吗?
Hadoop通过使用Partitioner来决定哪个Reducer将处理哪个输出密钥如果您只输出几个键,并且希望在reducer之间均匀分布,那么最好为您的输出数据实现一个自定义Partitioner。如
public class MyCustomPartitioner extends Partitioner<KEY, VALUE>
{
public int getPartition(KEY key, VALUE value, int numPartitions) {
// do something based on the key or value to determine which
// partition we want it to go to.
}
}
然后可以使用
在作业配置中设置这个自定义分区Job job = new Job(conf, "My Job Name");
job.setPartitionerClass(MyCustomPartitioner.class);
如果您想根据作业设置进行任何进一步的配置,您还可以在自定义Partitioner中实现Configurable接口。另外,检查您是否在配置中(查找"mapred.reduce.tasks")或代码中没有将reduce任务的数量设置为1,例如
job.setNumReduceTasks(1);