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

Use some datatype as input for a MapReduce job.

我正在处理一组 MapReduce 作业,这些作业将情节摘要列表转换为映射到电影 ID 的每个单词的索引以及它被使用的次数。我有一份工作接受输入并创建一个 linked 节点列表,其中包含单词、它来自的电影和次数。我的第二份工作采用这个 LinkedList 并使用单词作为键,使用电影 ID 和出现次数作为值,并吐出映射到每部电影的每个单词的索引以及出现次数。

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

我已阅读有关链接 MapReduce 作业的内容,因此请不要给我 link 到 Yahoo Developer 页面。

您在这里不需要两个 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 作业集相反。

效率扩展:

您可以通过在映射器输出中添加一个计数来提高效率 - 在当前的实现中,绘图线 "dog eat dog" 将导致地图输出:

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

而您可以通过添加计数器并在输出前扫描整行来将其减少为两条记录:

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

我不想通过包含这个使我的示例更复杂和更难阅读,但它应该很容易实现并且应该可以节省大量性能。