Mapreduce MultipleOutputs抛出异常

时间:2016-02-07 14:10:06

标签: java apache hadoop mapreduce

我正在尝试使用两个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);

它有效。

我不确定这意味着什么。 我可以看到它无法创建某个类的实例,但我不确定哪个类及其原因。

注意:我使用的是自定义数据类型,但这不是问题

0 个答案:

没有答案