java - Hadoop 将数据从映射器减少到组合器

标签 java hadoop

我有一个文本输入文件,其中包含一个 URL + 可变数量的关键字。这看起来像:

  1. facebook.com 社交新闻好友
  2. msn.com 新闻邮件
  3. yahoo.com 财经新闻

我需要将其转换为输出,例如:

  1. 社交 facebook.com
  2. 新闻 facebook.com msn.com yahoo.com
  3. friend facebook.com
  4. 金融 yahoo.com

我的映射器类如下所示:

public class KeywordsMapper extends Mapper<LongWritable, Text, Text, Text> {
private Text urlkey = new Text();
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
    String[] line = value.toString().split(" ");
    ArrayList<String> keywords = new ArrayList<String>();
    for (String sequence : line) {
        if (sequence.endsWith(".com")) {
            // url
            urlkey.set(sequence);
        } else {
            // keyword
            keywords.add(sequence);
        }
    }
    for (String keyword : keywords) {
        context.write(new Text(keyword), urlkey);
    }
}
}

我的 reducer /组合器类如下所示:

public class KeywordReducer extends Reducer<Text, Iterable<Text>, Text, Text> {
public void reduce(Text key,  Iterable<Text> values, Context context) throws IOException, InterruptedException {
    String body = "";
    for(Text part : values){
        body = body + " " + part.toString() + " ";
    }
    context.write(key, new Text(body));
}
}

工作看起来像这样:

public class KeywordJob extends Configured implements Tool{

@Override
public int run(String[] arg0) throws Exception {
    Job job = new Job(getConf());
    job.setJarByClass(getClass());
    job.setJobName(getClass().getSimpleName());

    FileInputFormat.addInputPath(job, new Path(arg0[0]));
    FileOutputFormat.setOutputPath(job, new Path(arg0[1]));

    job.setMapperClass(KeywordsMapper.class);
    job.setCombinerClass(KeywordReducer.class);
    job.setReducerClass(KeywordReducer.class);


    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(Text.class);

    return job.waitForCompletion(true) ? 0 : 1;
}

public static void main(String[]args) throws Exception{
    int rc = ToolRunner.run(new KeywordJob(), args);
    System.exit(rc);

}

}

我当前得到的输出是:

output

输入文件为:

yahoo.com news sports finance email celebrity
amazon.com shoes books jeans
google.com news finance email search
microsoft.com operating-system productivity search
target.com shoes books jeans groceries
wegmans.com books groceries
facebook.com news social sports
linkedin.com news recruitment

问题:我需要如何调整组合器/ reducer 才能获得所需的输出?输出包含多个重复键是否有特定原因,为什么它们没有合并?

最佳答案

马克,

reducer 没有被调用/调用。

reducer 类定义应该类似于 -

public class KeywordReducer extends Reducer<Text, Text, Text, Text> 

而不是

public class KeywordReducer extends Reducer<Text, Iterable<Text>, Text, Text> 

因为 map 输出应该与此相对应。 reduce() 方法签名是正确的。

希望这有帮助。

关于java - Hadoop 将数据从映射器减少到组合器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35357959/

相关文章:

java - 如何在 Java Junit 中测试异常

java - 在 Java 中收集数组中的用户输入并打印排序

java - 无法创建 Liferay 插件项目

hadoop - 保存 Hive 查询

java - 杀死 Hadoop 2.2.0 配置弃用信息消息的确切步骤

java - 如何检查2个类实例是否相同

hadoop - Pig Latin 语法错误

xml - Hadoop:XML文件如何存储到HDFS并被Mappers处理?

hadoop - org.apache.hadoop.hbase.NotServingRegionException : Region is not online: -ROOT-, ,0 这个错误背后的原因是什么

java - 从android中的另一个应用程序启动一个应用程序的Activity