我需要编写一个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端,当我收到与键对应的所有值时,我必须从第一个文件中减去第二个文件中的值。
所以我需要找出相应的值是来自第二个输入文件还是第一个文件。怎么办呢?
还有其他更好的方法吗?
答案 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支持。
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);
希望这会有所帮助。