我正在尝试使用两个reducer来写入同一个文件。 但是在运行时,我的工作失败了,例外:
16/02/07 19:18:16 INFO mapreduce.Job: Task Id : attempt_1454848920687_0006_r_000000_1, Status : FAILED
Error: java.lang.RuntimeException: java.lang.InstantiationException
at org.apache.hadoop.util.ReflectionUtils.newInstance(ReflectionUtils.java:134)
at org.apache.hadoop.mapreduce.lib.output.MultipleOutputs.getRecordWriter(MultipleOutputs.java:474)
at org.apache.hadoop.mapreduce.lib.output.MultipleOutputs.write(MultipleOutputs.java:432)
at org.apache.hadoop.mapreduce.lib.output.MultipleOutputs.write(MultipleOutputs.java:410)
at com.amar.stocks.TotalVolume$myReducer.reduce(TotalVolume.java:105)
at com.amar.stocks.TotalVolume$myReducer.reduce(TotalVolume.java:1)
at org.apache.hadoop.mapreduce.Reducer.run(Reducer.java:171)
at org.apache.hadoop.mapred.ReduceTask.runNewReducer(ReduceTask.java:627)
at org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:389)
at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:164)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:422)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1657)
at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:158)
Caused by: java.lang.InstantiationException
at sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:48)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at org.apache.hadoop.util.ReflectionUtils.newInstance(ReflectionUtils.java:132)
... 13 more
这是我的代码:
public class TotalVolume extends Configured implements Tool{
public int run(String[] args) throws Exception {
// TODO Auto-generated method stub
Job job = new Job(getConf(), "total volume");
job.setJarByClass(TotalVolume.class);
job.setMapperClass(myMapper.class);
job.setReducerClass(myReducer.class);
job.setNumReduceTasks(2);
job.setInputFormatClass(TextInputFormat.class);
job.setOutputFormatClass(TextOutputFormat.class);
job.setMapOutputKeyClass(CustomDataType.class);
job.setMapOutputValueClass(LongWritable.class);
job.setOutputKeyClass(NullWritable.class);
job.setOutputValueClass(LongWritable.class);
MultipleOutputs.addNamedOutput(job, "result", FileOutputFormat.class, CustomDataType.class, LongWritable.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
return job.waitForCompletion(true) ? 0 : 1;
}
public static final class myMapper extends Mapper<LongWritable, Text, CustomDataType, LongWritable> {
CustomDataType cdt = new CustomDataType();
Text stock = new Text();
IntWritable month = new IntWritable();
LongWritable volume = new LongWritable();
@Override
protected void map(LongWritable key, Text value,
Mapper<LongWritable, Text, CustomDataType, LongWritable>.Context context)
throws IOException, InterruptedException {
// TODO Auto-generated method stub
String record = value.toString();
String[] strArr = record.split("\t");
if(strArr.length == 9) {
stock.set(strArr[1]);
month.set(Integer.parseInt(strArr[2].split("-")[1]));
if(month.toString().equals("1"))
context.getCounter("test", "JAN_COUNTER").increment(1l);
cdt.setMonth(month);
cdt.setStockName(stock);
volume.set(Long.parseLong(strArr[7]));
context.write(cdt, volume);
}
}
}
public static final class myReducer extends Reducer<CustomDataType, LongWritable, NullWritable, LongWritable> {
MultipleOutputs<NullWritable, LongWritable> mos;
LongWritable sum = new LongWritable(0L);
Long result = new Long(0l);
@Override
protected void setup(Reducer<CustomDataType, LongWritable, NullWritable, LongWritable>.Context context)
throws IOException, InterruptedException {
mos = new MultipleOutputs(context);
}
@Override
protected void reduce(CustomDataType arg0, Iterable<LongWritable> arg1,
Reducer<CustomDataType, LongWritable, NullWritable, LongWritable>.Context arg2)
throws IOException, InterruptedException {
for (LongWritable longWritable : arg1) {
Long volume = Long.parseLong(longWritable.toString());
Long longSum = Long.parseLong(sum.toString());
result = (Long)volume + longSum;
sum.set(result);
}
mos.write("result", NullWritable.get(), sum, "output");
}
@Override
protected void cleanup(Reducer<CustomDataType, LongWritable, NullWritable, LongWritable>.Context context)
throws IOException, InterruptedException {
mos.close();
}
}
}
当我更换代码时
//mos.write("result", NullWritable.get(), sum, "output");
带
arg2.write(NullWritable.get(), sum);
它有效。
我不确定这意味着什么。 我可以看到它无法创建某个类的实例,但我不确定哪个类及其原因。
注意:我使用的是自定义数据类型,但这不是问题