【问题标题】:Use some datatype as input for a MapReduce job.使用一些数据类型作为 MapReduce 作业的输入。
【发布时间】:2015-11-13 11:20:22
【问题描述】:

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

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

我已阅读有关链接 MapReduce 作业的信息,因此请不要给我指向 Yahoo Developer 页面的链接。

【问题讨论】:

    标签: java hadoop mapreduce chaining


    【解决方案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")
    

    reducer 代码:

    //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","354757")
    ("eat","354757")
    ("dog","354757")
    

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

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

    我不想通过包含这个让我的示例变得更复杂和可读性更低,但它应该很容易实现并且应该可以很好地节省性能。

    【讨论】:

    • 感谢您的回答,但对于我的问题,我必须计算每个不同情节摘要的单词出现次数。例如:如果我有一个情节摘要“489373 the quick brown for jumps over a母牛”和“838399 the slow brown turtle bit a母牛”,输出示例将是“cow \t 489373 1,838399 1,”
    • 好吧,您在描述中并不清楚这一点,这令人沮丧,因为我在回答中付出了很多努力。我已经为提出的问题写了正确的答案。它仍然只是我的示例的一个小改动,让它为你工作,并且仍然不需要多个 MR 作业或自定义 Writables。这只是对 reducer 逻辑的一个小改动。
    • 很抱歉给您带来了困惑。所以要修改它,当reducer将所有movieID添加到moviesList时,会有重复,这意味着这个词在情节摘要中出现了多次。所以我只需要通过并简化电影列表。
    • 我现在已经更新我的答案是正确的 - 它使用 HashMap 来跟踪每部电影的出现次数。
    • 谢谢!如果我有足够的声誉,我会投票。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-25
    • 2012-04-30
    • 2012-11-23
    相关资源
    最近更新 更多