地图中的键类型不匹配:预期 .. 文本,已接收 ... LongWritable

Posted

技术标签:

【中文标题】地图中的键类型不匹配:预期 .. 文本,已接收 ... LongWritable【英文标题】:Type mismatch in key from map: expected .. Text, received ... 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)

【问题讨论】:

【参考方案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;

    确保映射器/缩减器的输入/输出是 o.a.h.io.Writable 类型。 Mapper的输入键为Object,设为LongWritable。

    看起来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#

【讨论】:

以上是关于地图中的键类型不匹配:预期 .. 文本,已接收 ... LongWritable的主要内容,如果未能解决你的问题,请参考以下文章

持久性无法将预期类型“键表”与实际类型文本匹配

Scala、Array[Int] 和 Array[Option[Int]] 中的类型不匹配

“查询结构与函数结果类型不匹配。返回类型双精度与第 1 列中的预期类型整数不匹配。”?

试图从一个文本文件中的行创建一个地图[字符串,字符串],不断收到错误[复制]

为啥我从对等端接收的数据与预期输出不匹配?

Presto 或 Trino 自定义 UDF 得到“不匹配预期的 Java 类型错误”