具有MultipleInputs的Hadoop映射器的控制流程是什么?

时间:2014-10-23 22:56:00

标签: java hadoop mapreduce

目标:实施Reduce Side Join

我的代码中目前有Job Chaining(两个工作)。现在我想在另一份工作中实现在reduce方面的加入。我必须采取多种投入:

Input #1:上一个减速机的输出 Input #2:来自HDFS的新文件实现加入。

看了一些关于如何使用MultipleInputs.addInputhPath(job, Path, InputFormat.class, Mapper.class);

的文章

所以我知道我必须使用它两次,一次用于Input #1,一次用于Input #2

Question 1:然后,如果我使用两个单独的映射器和一个reducer,将首先执行哪个映射器(或者它们将并行执行)?如何检查reducer端哪个映射器发出了<key, value>对?

Question 2:如果我使用单个映射器和单个reducer,那么控制流程是什么?

Question 3:更多的黑客,即不使用MultipleInputs
使用DistributedCache在reducer的Input #2方法中加载setup()是否可行(性能明智)?并将前一个reducer的输出作为该作业的唯一输入。

Note: Input #2文件的大小非常小。

1 个答案:

答案 0 :(得分:1)

回答1:
两个Mappers的Map任务应该运行并行提供的插槽可用。单个插槽的存在可能导致它们按顺序运行(可能有交错),但这不是正常情况。如果Mapper序列有一些配置,我就不知道这一点。

我再次怀疑任何api可用于识别哪个Mapper发出<key, value>。确切地说,只需要识别value,因为不同的地图可能会发出相同的key。这通常通过在输出值中添加前缀标记并在reducer中解析这些标记来实现。例如:

if(value.toString.startsWith("Input#1")){  //processing code }

看看这个blogpost,它有所有必需的提示和技巧。请注意,所有这些示例都使用旧的mapred api。但无论如何,逻辑都是一样的。

回答2:
 如果没有MultipleInputs,则Map中必须使用可用的Context对象标识传入对的文件名。例如:

public void map(LongWritable key, Text value, Context context)
    throws IOException, InterruptedException {
        String fileName = ((FileSplit) context.getInputSplit()).getPath().getName();   
        //............
}

然后只需将一个合适的标签添加到输出值,其余与answer1相同。

回答3:
这很棘手。当要添加到缓存的文件很小时,使用DistributedCache来加强提升性能。这可能是因为该作业现在以较少的Map任务运行。但它会对大文件产生不利影响。困境是要知道DistributedCache有多少字节被认为是小的。

由于您提到Input#2文件非常小,这应该是您最合适的解决方案。

注意:这篇文章的很多评论都是基于意见的。期待专家的投入。