word百分比程序

noj0wjuj  于 2021-06-04  发布在  Hadoop
关注(0)|答案(2)|浏览(391)

我正在开发一个著名的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没有任何用处,只会浪费处理器时间。

lfapxunr

lfapxunr1#

一种非优化的方法是创建一个特殊的单词(如“00000”),并使用它来计算所有单词。Map器1会为遇到的每个单词写出(word,1)和(“00000”,1)。reducer 1将计算所有的单词,并计算总数(计数为“00000”)。
下一个作业将有一个passthroughMap器,reducer将计算百分比。这里的诀窍是(1)有一个单一的减缩和(2)选择你的“00000”字,使它得到排序之前,所有其他字。通过这种方式,总数首先被传递到reducer 2,并且对于所有后续的字数计数都是已知的。

oo7oh9g9

oo7oh9g92#

关于使用单个作业的一个想法: total_count 可以从第一个作业的Map阶段计算。实际上,它已经被算作 MAP_OUTPUT_RECORDS . 这是所有Map输出的总和 (key, value) 对。所以,如果你总是有1作为值,那么这个总和就是你想要的,也就是你的文档中的总字数(有重复)。
现在,我不知道你能不能在减速机的配置中得到这个计数器。然后,您可以只输出对中的每个单词 (word, wordCount/MAP_OUTPUT_RECORDS) . 我认为你可以通过以下方式做到:
新api:

context.getCounter("org.apache.hadoop.mapred.Task$Counter", "MAP_OUTPUT_RECORDS").getValue();

旧api:

reporter.getCounter("org.apache.hadoop.mapred.Task$Counter", "MAP_OUTPUT_RECORDS").getValue();

相关问题