我问的两个问题的解释在这篇文章的结尾。
我正在试着运行一个简单的wordcount程序,这样我就可以到处玩了,看看有什么用。
我目前有一个实现,似乎运行非常好的结束。在main()中的最后一行(println就是这么说的)之后,我得到的输出看起来像是hadoop作业的摘要,只有一个异常。
在我的mapper和reducer函数中,我也有一行,它只是简单地将任意文本输出到屏幕上,这样我就知道它命中了该行,但是在运行期间,我从来没有看到这些行中的任何一行被命中。我相信这是造成上述ioexception的原因。
我有两个问题:
为什么我要把我的课程 setMapperClass()
, setCombinerClass()
以及 setReducerClass()
不被处决?
“i hit the end of main()”行后面的输出是什么意思?这些是作为java应用程序的一部分显示的,还是来自正在处理的作业的hadoop安装的系统消息?因为它引用了我在代码中使用的hadoopapi,所以我假设它是java应用程序的一部分。如果这是真的,为什么要在main()函数的最后一行之后执行呢?
我已将运行作业的输出保存到一个文件中:
Enter the Code to run the particular program.
Wordcount = 000:
Assignment 1 = 001:
Assignment 2 = 002:
000
/usr/dan/wordcount/
/usr/dan/wordcount/result.txt
May 04, 2014 2:22:28 PM org.apache.hadoop.metrics.jvm.JvmMetrics init
INFO: Initializing JVM Metrics with processName=JobTracker, sessionId=
May 04, 2014 2:22:29 PM org.apache.hadoop.mapreduce.lib.input.FileInputFormat listStatus
INFO: Total input paths to process : 2
May 04, 2014 2:22:29 PM org.apache.hadoop.mapred.JobClient monitorAndPrintJob
INFO: Running job: job_local_0001
May 04, 2014 2:22:29 PM org.apache.hadoop.mapreduce.lib.input.FileInputFormat listStatus
INFO: Total input paths to process : 2
May 04, 2014 2:22:29 PM org.apache.hadoop.mapred.MapTask <init>
INFO: io.sort.mb = 100
May 04, 2014 2:22:29 PM org.apache.hadoop.mapred.MapTask <init>
INFO: data buffer = 79691776/99614720
May 04, 2014 2:22:29 PM org.apache.hadoop.mapred.MapTask <init>
INFO: record buffer = 262144/327680
May 04, 2014 2:22:29 PM org.apache.hadoop.mapred.LocalJobRunner run
WARNING: job_local_0001
java.io.IOException: Type mismatch in key from map: expected org.apache.hadoop.io.Text, recieved org.apache.hadoop.io.LongWritable
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.collect(MapTask.java:845)
at org.apache.hadoop.mapred.MapTask$NewOutputCollector.write(MapTask.java:541)
at org.apache.hadoop.mapreduce.TaskInputOutputContext.write(TaskInputOutputContext.java:80)
at org.apache.hadoop.mapreduce.Mapper.map(Mapper.java:124)
at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:144)
at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:621)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:305)
at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:177)
May 04, 2014 2:22:30 PM org.apache.hadoop.mapred.JobClient monitorAndPrintJob
INFO: map 0% reduce 0%
May 04, 2014 2:22:30 PM org.apache.hadoop.mapred.JobClient monitorAndPrintJob
INFO: Job complete: job_local_0001
May 04, 2014 2:22:30 PM org.apache.hadoop.mapred.JobClient log
INFO: Counters: 0
Not Fail!
I hit the end of wordcount!
I hit the end of Main()
我设置应用程序的方式是主类,它基于用户输入将流发送到相应的类。如果有帮助的话,我将只发布我目前正在学习的课程。如果你想看更多的,尽管问。
package hadoop;
import java.io.IOException;
import java.util.Arrays;
import java.util.StringTokenizer;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.util.GenericOptionsParser;
/**
*
* @author Dans Laptop
*/
public class Wordcount {
public static class TokenizerMapper
extends org.apache.hadoop.mapreduce.Mapper<Object, Text, Text, IntWritable>{
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
public void map(Object key, Text value, org.apache.hadoop.mapreduce.Reducer.Context context
) throws IOException, InterruptedException {
System.out.println("mapper!");
StringTokenizer itr = new StringTokenizer(value.toString());
while (itr.hasMoreTokens()) {
word.set(itr.nextToken());
context.write(word, one);
}
}
}
public static class IntSumReducer
extends org.apache.hadoop.mapreduce.Reducer<Text,IntWritable,Text,IntWritable> {
private IntWritable result = new IntWritable();
public void reduce(Text key, Iterable<IntWritable> values,
org.apache.hadoop.mapreduce.Reducer.Context context
) throws IOException, InterruptedException {
System.out.println("Reducer!");
int sum = 0;
for (IntWritable val : values) {
sum += val.get();
}
result.set(sum);
context.write(key, result);
}
}
public void wordcount(String[] args) throws IOException, InterruptedException, ClassNotFoundException{
System.out.println(args[0]);// Prints arg 1
System.out.println(args[1]);// Prints arg 2
Configuration conf = new Configuration();
String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
if (otherArgs.length != 2) {
System.err.println("Usage: wordcount <in> <out>");
System.exit(2);
}
Job job = new Job(conf, "wordcount");
job.setJarByClass(Wordcount.class);
job.setMapperClass(TokenizerMapper.class);
job.setCombinerClass(IntSumReducer.class);
job.setReducerClass(IntSumReducer.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));
try{
job.waitForCompletion(true);
System.out.println("Not Fail!");
}catch(Exception e){
System.out.println(e.getLocalizedMessage());
System.out.println(e.getMessage());
System.out.println(Arrays.toString(e.getStackTrace()));
System.out.println(e.toString());
System.out.println("Failed!");
}
System.out.println("I hit the end of wordcount!");//Proves I hit the end of wordcount.
}
}
用于运行jar的命令是(从位置/usr/dan):
hadoop -jar ./hadoop.jar /usr/dan/wordcount/ /usr/dan/wordcount/result.txt
注意:我希望程序查看/usr/dan/wordcount中的所有文件,然后创建一个文件/usr/dan/wordcount/result.txt,其中列出每个单词及其出现的次数。我还没有得到这种行为,但我想找出这两个问题,我有这样我可以解决它的方式休息。
回复@alexey:
我没有意识到在hadoop中mapreduce作业执行期间无法直接打印到控制台。我以为那条线没有被执行。现在我知道了在工作中应该在哪里寻找输出。但是,按照你所链接的问题的说明,没有显示任何工作给我看。可能是因为我还没有完全完成任何工作,虽然。
我已经从 job.submit();
至 job.waitForCompletion(true);
但我还是得到了它之后的输出。我不知道这是否表明有什么不对劲,但我想我会把它记录下来。
我已经添加了您建议的行(这些行仅设置map类的输出?):
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);
左/删除行(设置map和reduce类的输出?):
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
我仍然得到同样的例外。从网上阅读的信息来看,这个错误似乎与map类的输出类型与reduce类的输入类型不匹配有关。在我的代码中,这两个值的匹配似乎非常明确。唯一让我困惑的是它是从哪里来的?我的代码里没有这个。在研究了这个问题之后,hadoop在key from map expected value text received value longwritable中的类型不匹配情况与此相同,但解决方案是指定mapper和reducer类,我已经在这样做了。我在代码中注意到的另一件事是Map器类的输入键是object类型。这有什么意义吗?不过,错误显示这是来自map的键不匹配。
我还继续更新了我的代码/结果。
谢谢你的帮助,我已经从你的回复中得到了很多信息。
解释
mapper和reducer函数正在执行,但任何输出都不会直接显示在屏幕上。您必须在浏览器中查看hadoop日志才能看到它们。
额外的输出是hadoop提供的一些关于作业如何执行的信息(如果有的话)。
我问@alexey的任何其他问题都超出了最初问题的范围,但我下定决心把它们解决了,学到了更大的程度。谢谢你@alexey。
1条答案
按热度按时间q8l4jmvw1#
您的第一个问题看起来类似于这个问题:如何在hadoop中的mapreduce作业执行期间在控制台上打印。
线路
job.submit();
告诉hadoop运行作业,但不要等到作业完成。我想你可能想把这条线换成job.waitForCompletion(true);
,因此在“i hit the end of wordcount!”之后将没有输出。要消除异常,应指定Map器的输出键和值类:
job.setmapoutputkeyclass(text.class);job.setmapoutputvalueclass(intwritable.class);