java - Hadoop 的单词百分比程序

标签 java hadoop mapreduce word-count

我正在开发著名的 WordCount 程序的一个稍微改进的版本,它应该输出该单词在书中所占的百分比。例如:

...
war 0.00002332423%
peace 0.0034234324%
...

基本上,我需要计算所有单词的数量,计算每个单词的出现次数,然后将这组值除以总数。所以至少应该有两个工作:

作业1

  • 获取input目录并生成两个输出目录:output1output2
  • 映射器:将 (word, 1) 对写入到 output1,将对 ("total_count", 1) 写入 output2
  • Reducer:将具有相同键的对求和,以在 output1 中生成 (word, n),计算总计数以生成 ("total_count", N )output2

作业2

  • output1output2 作为输入文件夹,将结果写入 output3
  • Mapper:不做任何事情,只是写下它得到的相同对
  • Reducer:获取单个值并将其除以 total_count,将结果写入 output3

我的问题:

  1. 我想避免两次查看原始输入,这就是为什么我尝试计算 Job1 中的字数和总计数。但我不明白如何避免混淆一个输出中的结果。我尝试过使用 MultipleOutputs,但在这种情况下,映射器的结果不会进入 reducer 。

  2. Job2 需要多个输入,而且它需要先读取 output2,因为没有总计数,从 output1 读取结果是没有用的。我觉得这是使用 MapReduce 的错误方式(我们不应该使用任何类型的同步),但没有看到正确的方式。

  3. Job2 中的映射器没有做任何有用的事情,只会浪费处理器时间。

最佳答案

关于使用单个作业的想法:

total_count 可以从第一个作业的映射阶段计算出来。实际上,它已经被计为MAP_OUTPUT_RECORDS。这是所有映射输出 (key, value) 对的总和。因此,如果您始终将 1 作为值,那么这个总和就是您想要的,即文档中的单词总数(包含重复)。

现在,我不知道你是否可以在 reducer 的配置中获得这个计数器。然后,您可以为每个单词输出对 (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();

关于java - Hadoop 的单词百分比程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22357561/

相关文章:

java - 无法在java中解析美国格式的日期

java - 线程 “main”中的ExException java.lang.IllegalArgumentException:/home不能是目录

r - 如果 1 个 reducer (RHadoop)的数据变大怎么办?

java - 我无法理解 ExceptionError 代码的一部分

java - 我无法从嵌入 json 的数组中获取数据。使用改造和 GSON

java - 如果条件满足,如何转到Android中的另一个 Activity ?

hadoop - 在hadoop中,我只想在每个节点上执行自己自定义的程序

java - 如何重写驱动程序类中的 'mapred.user.jobconf.limit'值?

java - 尝试运行 HBase map reduce 时出错

java - Hadoop Map-Reduce 。记录阅读器