【问题标题】:Type mismatch in key from map: expected .. Text, received ... LongWritable地图中的键类型不匹配:预期 .. 文本,已接收 ... LongWritable
【发布时间】:2012-01-22 11:04:20
【问题描述】:

我有一个简单的 hadoop 应用程序,它获取一个 CSV 文件,然后用“,”分割条目,然后计算第一个项目。

以下是我的代码。

包 com.bluedolphin; 导入 java.io.IOException; 导入 java.util.Iterator; 导入 org.apache.hadoop.conf.Configuration; 导入 org.apache.hadoop.conf.Configured; 导入 org.apache.hadoop.fs.Path; 导入 org.apache.hadoop.io.IntWritable; 导入 org.apache.hadoop.io.LongWritable; 导入 org.apache.hadoop.io.Text; 导入 org.apache.hadoop.mapred.OutputCollector; 导入 org.apache.hadoop.mapred.Reporter; 导入 org.apache.hadoop.mapreduce.Job; 导入 org.apache.hadoop.mapreduce.Mapper; 导入 org.apache.hadoop.mapreduce.Reducer; 导入 org.apache.hadoop.mapreduce.lib.input.FileInputFormat; 导入 org.apache.hadoop.mapreduce.lib.input.TextInputFormat; 导入 org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; 导入 org.apache.hadoop.util.Tool; 导入 org.apache.hadoop.util.ToolRunner; 公共类 MyJob 扩展配置实现工具 { private final static LongWritable one = new LongWritable(1); 公共静态类 MapClass 扩展 Mapper { 私人文本字=新文本(); 公共无效映射(对象键, 文本值, OutputCollector 输出, 记者记者)抛出 IOException,InterruptedException { String[] 引用 = value.toString().split(","); word.set(引文[0]); output.collect(单词,一个); } } 公共静态类 Reduce 扩展 Reducer { 公共无效减少( 文字键, 迭代器 值, OutputCollector 输出, 记者记者)抛出 IOException,InterruptedException { 整数总和 = 0; while (values.hasNext()) { sum += values.next().get(); } output.collect(key, new LongWritable(sum)); } } 公共静态类 Combiner 扩展 Reducer { 公共无效减少( 文字键, 迭代器 值, OutputCollector 输出, 记者记者)抛出 IOException,InterruptedException { 整数总和 = 0; while (values.hasNext()) { sum += values.next().get(); } output.collect(key, new LongWritable(sum)); } } public int run(String[] args) 抛出异常 { 配置 conf = getConf(); 工作工作 = 新工作(conf,“我的工作”); job.setJarByClass(MyJob.class); 路径 in = new Path(args[0]); 路径输出 = 新路径(args[1]); FileInputFormat.setInputPaths(job, in); FileOutputFormat.setOutputPath(job, out); job.setMapperClass(MapClass.class); // job.setCombinerClass(Combiner.class); job.setReducerClass(Reduce.class); // job.setInputFormatClass(KeyValueInputFormat.class); job.setInputFormatClass(TextInputFormat.class); // job.setOutputFormatClass(KeyValueOutputFormat.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(LongWritable.class); System.exit(job.waitForCompletion(true) ? 0 : 1); 返回0; } 公共静态 void main(String args[]) 抛出异常 { int res = ToolRunner.run(new Configuration(), new MyJob(), args); System.exit(res); } }

这是错误:

2016 年 11 月 12 日 22:16:58 信息 mapred.JobClient:任务 ID:尝试_201112161948_0005_m_000000_0,状态:失败 java.io.IOException:映射中的键类型不匹配:预期 org.apache.hadoop.io.Text,收到 org.apache.hadoop.io.LongWritable 在 org.apache.hadoop.mapred.MapTask$MapOutputBuffer.collect(MapTask.java:1013) 在 org.apache.hadoop.mapred.MapTask$NewOutputCollector.write(MapTask.java:690) 在 org.apache.hadoop.mapreduce.TaskInputOutputContext.write(TaskInputOutputContext.java:80) 在 org.apache.hadoop.mapreduce.Mapper.map(Mapper.java:124) 在 org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:144) 在 org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:763) 在 org.apache.hadoop.mapred.MapTask.run(MapTask.java:369) 在 org.apache.hadoop.mapred.Child$4.run(Child.java:259) 在 java.security.AccessController.doPrivileged(本机方法) 在 javax.security.auth.Subject.doAs(Subject.java:416) 在 org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1059) 在 org.apache.hadoop.mapred.Child.main(Child.java:253)

【问题讨论】:

    标签: java hadoop


    【解决方案1】:

    代码中需要修复的几件事

    1. 旧 API (o.a.h.mapred) 和新 API (o.a.h.mapreduce) 不兼容,因此不应混用。

    import org.apache.hadoop.mapred.OutputCollector;  
    import org.apache.hadoop.mapred.Reporter;  
    import org.apache.hadoop.mapreduce.Job;  
    import org.apache.hadoop.mapreduce.Mapper;  
    import org.apache.hadoop.mapreduce.Reducer;
    
    1. 确保映射器/缩减器的输入/输出是 o.a.h.io.Writable 类型。 Mapper的输入键为Object,设为LongWritable。

    2. 看起来Combiner和Reducer的功能是一样的,就不用重复了。

    job.setCombinerClass(Reducer.class);
    

    另外,您可以使用WordCount 示例,您的要求与 WordCount 示例之间没有太大区别。

    【讨论】:

    • 和>被页面条带化,所以我将它们转义并添加回来,请再看一下。谢谢。
    • 很老的帖子,但我必须说Combiner的使用并不是多余的:它是用来提高工作性能的,请参阅wiki.apache.org/hadoop/HadoopMapReduce
    【解决方案2】:

    一般说明,如果我们有Mapper<K1,V1, K2,V2>Reducer<K2,V2, K3,V3>,最好(在作业中)声明以下内容

    JobConf conf = new JobConf(MyJob.class);
    ...
    conf.setMapOutputKeyClass(K2.class);
    conf.setMapOutputValueClass(V2.class);
    

    你可以看到另一个例子here

    【讨论】:

      【解决方案3】:

      旧 API (o.a.h.mapred) 和新 API (o.a.h.mapreduce) 不兼容,因此不应混用。

      import org.apache.hadoop.mapred.OutputCollector;
      import org.apache.hadoop.mapred.Reporter;
      import org.apache.hadoop.mapreduce.Job;
      import org.apache.hadoop.mapreduce.Mapper;
      import org.apache.hadoop.mapreduce.Reducer;
      

      您应该尝试将 Map 和 Reduce 函数签名中的 OutputCollector 和 Reporter 替换为 Context。 map(K1 key,V1 val,Context context) 和 output.collect(k,v) with context.write(k,v)

      作为参考,请使用此链接了解有关迁移到新 API 的更多详细信息 http://www.slideshare.net/sh1mmer/upgrading-to-the-new-map-reduce-api#

      【讨论】:

        猜你喜欢
        • 2017-08-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-16
        • 2021-07-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多