使用单个映射器和两个不同的reducer进行hadoop工作

时间:2014-06-23 09:58:27

标签: hadoop mapreduce

我有一个大型文档语料库作为MapReduce作业(旧的hadoop API)的输入。在映射器中,我可以产生两种输出:一种是计数单词,另一种是产生minHash签名。我需要做的是:

  1. 将计数输出一词给一个reducer类(一个典型的WordCount减速器)和
  2. 将minHash签名提供给另一个reducer类(对存储桶的大小执行一些计算)。
  3. 输入是同一文档语料库,无需处理两次。我认为MultipleOutputs不是解决方案,因为我找不到将Mapper输出提供给两个不同Reduce类的方法。

    简而言之,我需要的是以下内容:

                   WordCounting Reducer   --> WordCount output
                 / 
    
         

    输入 - > Mapper

                 \ 
                  MinHash Buckets Reducer --> MinHash output
    

    有没有办法使用相同的Mapper(在同一个工作中),还是应该将它分成两个工作?

2 个答案:

答案 0 :(得分:4)

你可以做到,但它将涉及一些编码技巧(分区程序和前缀约定)。想法是让mapper输出前缀为" W:"和minhash前缀为" M:"。比使用分区程序来决定它需要进入哪个分区(也称为reducer)。

伪代码 主要方法:

Set number of reducers to 2

MAPPER:

.... parse the word ...
... generate minhash ..
context.write("W:" + word, 1);
context.write("M:" + minhash, 1);

分区:

IF Key starts with "W:" { return 0; } // reducer 1
IF Key starts with "M:" { return 1; } // reducer 2

IF Key starts with "W:" { iterate over values and sum; context.write(Key, SUM); return;} 
Iterate and context.write all of the values

减速机:

IF Key starts with "W:" { iterate over values and sum; context.write(Key, SUM); return;} 
IF Key starts with "M:" { perform min hash logic }

在输出部分-0000中将是字数和部分0001的最小哈希计算。

不幸的是,不可能提供不同的Reducer类,但使用IF和前缀可以模拟它。

从性能的角度来看,只有2个减少器可能效率不高,而且可以使用分区器将前N个分区分配给字数。

如果您不喜欢前缀构思,那么您需要使用自定义WritableComparable类为密钥实现二级排序。但只有在更复杂的情况下才值得努力。

答案 1 :(得分:0)

AFAIK这在单个map reduce工作中是不可能的,只有默认的输出文件部分--r - 0000文件将被送到reducer,所以如果你创建两个命名为WordCount的多个命名输出 - m - 0和MinHash - m - 0

您可以使用Identity Mapper和相应的Reducers创建另外两个不同的Map / Reduce作业,将输入指定为hdfspath / WordCount - *和hdfspath / MinHash - *作为相应作业的输入。