map reduce用两个输入文件,一个文件根据另一个

时间:2015-08-14 14:23:40

标签: java hadoop mapreduce hadoop-partitioning

我需要编写一个map reduce,它将输入作为两个输入文件。 第一个输入文件如下所示:

key1 , 25
key1 , 35
key1 , 60
key2 , 30
key3 , 45
key3 , 65

第二个输入文件如下:

key1, -10
key2, -20
key3, -15

我需要输出:

key1 , 15
key1 , 25
key1 , 50
key2 , 10
key3 , 30
key3 , 50

(输出是第一个输入文件的值减去第二个输入文件)

怎么可以这样做? mapper和reducer任务将如何显示?

我的方法如下:

我想我必须有两个映射器,每个输入文件一个(可以用一个映射器来读取这两个文件吗?)。 Mappers只会发出密钥和值。

在reducer端,当我收到与键对应的所有值时,我必须从第一个文件中减去第二个文件中的值。

所以我需要找出相应的值是来自第二个输入文件还是第一个文件。怎么办呢?

还有其他更好的方法吗?

2 个答案:

答案 0 :(得分:1)

读入单独的映射器,并更改内容,以便您知道它们来自哪个文件。例如输出

key1 , 25 , file1
key1 , 35 , file1
key1 , 60 , file1
key2 , 30 , file1
key3 , 45 , file1
key3 , 65 , file1

key1, -10 , file2
key2, -20 , file2
key3, -15 , file2

然后,您可以同时通过单个mapreduce阶段输出,并且您将知道哪个来自哪里,并且您可以在减速器中相应地操作您的数据。

答案 1 :(得分:1)

这可以在一个MapReduce程序中完成。您可以使用MapReduce框架中的MultipleInputs支持。

  • 为每个输入文件定义两个映射器类。然后输出键,值为键#fileName,值对。
  • 定义自定义分区程序,该分区程序仅考虑实际密钥并忽略附加的fileName以对数据进行分区。这样两个文件中的相同键都会转到同一个reducer。
  • reducer将从file1获取key的值列表。在内存中保存此值列表,并从file2获取值列表以及相同的键。这两个将连续出现,因为我们只在关键部分上划分数据,比较器也将按键值对它们进行排序。假设第一个文件名按字母顺序排列。然后使用第二个文件值在第一个文件值列表上执行它们所需的操作。

    Configuration conf = new Configuration();
    Job job = new Job(conf, "aggprog");        
    
    MultipleInputs.addInputPath(job,new Path(args[0]),TextInputFormat.class,MapperOne.class);
    MultipleInputs.addInputPath(job,new Path(args[1]),TextInputFormat.class,MapperTwo.class);
    
    conf.setPartitionerClass(CustomPartitioner.class);
    

    希望这会有所帮助。