使用某种数据类型作为MapReduce作业的输入。

时间:2015-11-13 11:20:23

标签: java hadoop mapreduce chaining

我正在研究一组MapReduce作业,它们将绘图摘要列表转换为映射到movieID的每个单词的索引以及使用它的次数。我有一个工作,它接受输入并创建一个链接的节点列表,其中包含单词,它来自的电影和次数。我的第二个工作是使用这个LinkedList,并使用单词作为键,将movieID和出现次数作为值,并将每个映射到它所用的电影的每个单词的索引以及出现次数。

调用FileInputFormat.addInputPath()时,我可以使用Path()或String,每个元素用逗号分隔。拥有一个包含LinkedList所有数据的大量字符串并不难,但让映射器使用LinkedList作为输入会更好。

我已经阅读了关于链接MapReduce工作的内容,所以请不要给我一个指向Yahoo Developer页面的链接。

1 个答案:

答案 0 :(得分:1)

这里你不需要两个MapReduce作业(或者因此是一个LinkedList)。我们可以将此视为单词计数的变体,但将输入的电影ID列表添加到其中。

地图输入:

354757\tToys come alive
432984\tMore toys

地图代码:

String[] idAndWords = input.split("\\t");

for(String word : idAndWords[1].split(" ")) {
    //Do whatever cleansing you want here - remove punctuation, lowercase etc.
    output.write(word,idAndWords[0]);
}

地图输出

("toys","354757")
("come","354757")
("alive","354757")
("more","432984")
("toys","432984")

减速机代码:

//Maps movie IDs to occurrences
Map<String,Int> movieMap = new HashMap<>();
//In here is the list of movie IDs for each word
for(String val : values) {
    if(!movieMap.contains(val)) {
        movieMap.put(val,1);
    } else {
        movieMap.put(val,movieMap.get(val)+1);
    }
}
output.write(NullWritable.get(),key+"\t"+movieMap);

减速机输出:

toys\t[(3547571),(432984,1)]
come\t[(354757,1)]
alive\t[(354757,1)]
more\t[(432984,1)]

现在你不需要自定义Writable,而且它只需要不到十几行逻辑,而不是我认为这是一套非常复杂的两个连锁MR作业。

效率扩展:

你可以通过在mapper输出中添加一个计数来提高效率 - 使用当前的实现,然后是情节线&#34;狗吃狗&#34;会导致地图输出:

("dog","354757")
("eat","354757")
("dog","354757")

然而,您可以通过添加计数器并在输出之前扫描整行来将其缩小为两个记录:

("dog","354757\t2")
("eat","354757\t1")

我不想通过包含这个来使我的示例更复杂,更不易阅读,但实施起来应该是微不足道的,应该可以节省很多性能。