我正在开发一个著名的wordcount程序的稍微改进的版本,它应该输出单词占图书的百分比。例如:
...
war 0.00002332423%
peace 0.0034234324%
...
基本上,我需要计算所有的单词,计算每个单词的出现次数,将这组值除以总计数。所以至少应该有两份工作:
工作1
拿 input
目录并生成两个输出目录: output1
以及 output2
Map器:写入对 (word, 1)
至 output1
,写入对 ("total_count", 1)
至 output2
减速机:将具有相同键的对加起来以生成 (word, n)
在 output1
,计算要进行的总计数 ("total_count", N)
在 output2
工作2
拿 output1
以及 output2
作为输入文件夹,将结果写入 output3
mapper:什么都不做,只写下它得到的同一对
reducer:取单个值并除以 total_count
,将结果写入 output3
我的问题:
我希望避免两次检查原始输入,这就是为什么我要在job1中同时计算字数和总数。但我不明白如何避免在一个输出中混淆结果。我试过使用 MultipleOutputs
但在这种情况下,Map器的结果不会进入reducer。
job2需要多个输入,而且需要读取 output2
首先,因为没有总数,从中读取结果是无用的 output1
. 我觉得这是使用mapreduce的错误方法(我们不应该使用任何类型的同步),但是看不到正确的方法。
job2中的mapper没有任何用处,只会浪费处理器时间。
2条答案
按热度按时间lfapxunr1#
一种非优化的方法是创建一个特殊的单词(如“00000”),并使用它来计算所有单词。Map器1会为遇到的每个单词写出(word,1)和(“00000”,1)。reducer 1将计算所有的单词,并计算总数(计数为“00000”)。
下一个作业将有一个passthroughMap器,reducer将计算百分比。这里的诀窍是(1)有一个单一的减缩和(2)选择你的“00000”字,使它得到排序之前,所有其他字。通过这种方式,总数首先被传递到reducer 2,并且对于所有后续的字数计数都是已知的。
oo7oh9g92#
关于使用单个作业的一个想法:
total_count
可以从第一个作业的Map阶段计算。实际上,它已经被算作MAP_OUTPUT_RECORDS
. 这是所有Map输出的总和(key, value)
对。所以,如果你总是有1作为值,那么这个总和就是你想要的,也就是你的文档中的总字数(有重复)。现在,我不知道你能不能在减速机的配置中得到这个计数器。然后,您可以只输出对中的每个单词
(word, wordCount/MAP_OUTPUT_RECORDS)
. 我认为你可以通过以下方式做到:新api:
旧api: