2014-11-18 5 views
0

MR 작업에 대해 다음과 같은 클래스가 있지만 작업을 실행할 때 작업이 실패하고 아래의 예외가 있음을 알 수 있습니다. 다음과 같은 예외로 WritableComparable 객체가 직렬화 가능하지 않습니다.

public class MongoKey implements WritableComparable<MongoKey> { 
    ... 
    private Text name; 
private Text place; 

public MongoKey() { 

    this.name = new Text(); 
    this.place = new Text(); 

} 

public MongoKey(Text name, Text place) { 

    this.name = name; 
    this.place = place; 

} 

public void readFields(DataInput in) throws IOException { 

    name.readFields(in); 
    place.readFields(in); 

} 

public void write(DataOutput out) throws IOException { 

    name.write(out); 
    place.write(out); 

} 
    public int compareTo(MongoKey o) { 

      MongoKey other = (MongoKey)o; 
      int cmp = name.compareTo(other.name); 
      if(cmp != 0){ 
       return cmp; 
      } 

      return place.compareTo(other.place); 
     } 
    } 

public class MongoValue implements Writable { 
... 
public void readFields(DataInput in) throws IOException { 

     profession.readFields(in); 
    } 

    public void write(DataOutput out) throws IOException { 

     profession.write(out); 
    } 
} 

public class MongoReducer extends Reducer<MongoKey, MongoValue, MongoKey, BSONWritable> { 

... 
context.write(key, new BSONWritable(output)); // line 41 
} 

public class MongoHadoopJobRunner extends Configured implements Tool { 

    public int run(String[] args) throws Exception { 

     if (args.length != 2) { 
      System.out.println("usage: [input] [output]"); 
      System.exit(-1); 
     } 

     Configuration conf = getConf(); 
     for (String arg : args) 
      System.out.println(arg); 
     GenericOptionsParser parser = new GenericOptionsParser(conf, args); 

     conf.set("mongo.output.uri", "mongodb://localhost/demo.logs_aggregate"); 

     MongoConfigUtil.setOutputURI(conf, "mongodb://localhost/demo.logs_aggregate"); 
     MongoConfigUtil.setOutputFormat(conf, MongoOutputFormat.class); 

     final Job job = new Job(conf, "mongo_hadoop"); 
     job.setOutputFormatClass(MongoOutputFormat.class); 
     // Job job = new Job(); 

     job.setJarByClass(MongoHadoopJobRunner.class); 

     // job.setJobName("mongo_hadoop"); 
     job.setNumReduceTasks(1); 

     job.setMapperClass(MongoMapper.class); 
     job.setReducerClass(MongoReducer.class); 

     job.setMapOutputKeyClass(MongoKey.class); 
     job.setMapOutputValueClass(MongoValue.class); 

     job.setOutputKeyClass(MongoKey.class); 
     job.setOutputValueClass(BSONWritable.class); 

     job.setInputFormatClass(MongoInputFormat.class); 
     for (String arg2 : parser.getRemainingArgs()) { 
      System.out.println("remaining: " + arg2); 
     } 
     Path inPath = new Path(parser.getRemainingArgs()[0]); 
     MongoInputFormat.addInputPath(job, inPath); 

     job.waitForCompletion(true); 

     return 0; 
    } 

    public static void main(String[] pArgs) throws Exception { 
     Configuration conf = new Configuration(); 
     for (String arg : pArgs) { 
      System.out.println(arg); 
     } 
     GenericOptionsParser parser = new GenericOptionsParser(conf, pArgs); 
     for (String arg2 : parser.getRemainingArgs()) { 
      System.out.println("ree" + arg2); 
     } 
     System.exit(ToolRunner.run(conf, new MongoHadoopJobRunner(), parser 
       .getRemainingArgs())); 
    } 

} 

java.lang.Exception: java.lang.IllegalArgumentException: can't serialize class com.name.custom.MongoKey 
... 
... 
at com.mongodb.hadoop.output.MongoRecordWriter.write(MongoRecordWriter.java:93) 
    at org.apache.hadoop.mapred.ReduceTask$NewTrackingRecordWriter.write(ReduceTask.java:558) 
    at org.apache.hadoop.mapreduce.task.TaskInputOutputContextImpl.write(TaskInputOutputContextImpl.java:89) 
    at org.apache.hadoop.mapreduce.lib.reduce.WrappedReducer$Context.write(WrappedReducer.java:105) 
    at com.name.custom.MongoReducer.reduce(MongoReducer.java:41) 
    at com.name.custom.MongoReducer.reduce(MongoReducer.java:11) 

내가 완전히 우둔 오전 필드를 직렬화 할 수는없는 임의의 코드에 문제가 그런데 왜이 안 보인다. 사전

+0

어떻게'MongoKey.write'가 구현 되었습니까? –

+0

이 게시물을 업데이트하여 자세한 내용을 보았습니다. 간단한 텍스트 인스턴스를 읽고 쓰고 있습니다. – Raghuveer

+0

'MongoRecordWriter'는 임의의'WritableComparable'을 키로 지원하지 않습니다. 'MongoRecordWriter'의'write' 메소드 참조 http://grepcode.com/file/repo1.maven.org/maven2/org.mongodb/mongo-hadoop-core/1.3.0/com/mongodb/hadoop/output/MongoRecordWriter .java # MongoRecordWriter.write % 28java.lang.Object % 2Cjava.lang.Object % 29. –

답변

0

내가 MongoRecordWritersource code에서 보듯이 매우 많이

덕분에 그것은 키로 임의 WritableComparable 객체를 지원하지 않습니다. 다음 클래스 중 하나를 키로 사용할 수 있습니다 : BSONWritable, BSONObject, Text, UTF8, 간단한 래퍼 IntWritable. 또한 Serializable 개체를 키로 사용할 수 있다고 생각합니다. 당신의 MongoKeyserializable (implements Serializable 구현 writeObject, readObject 방법을) 확인

  1. : 그래서 나는 당신에게 두 가지 해결 방법을 제안 할 수 있습니다. Text key = new Text(name.toString() + "\t" + place.toString());
+0

Writable 또는 WritableComparable을 구현하면 serializable이되므로 왜 다시해야하는지 생각합니다. – Raghuveer

+0

'Writable'을 구현하면 hadoop 프레임 워크에 대해 객체를 직렬화 할 수 있지만 객체는 여전히 Java 측면에서 직렬화 할 수 없습니다. 예를 들어'Writable' 객체를'ObjectOutputStream' (https://docs.oracle.com/javase/7/docs/api/java/io/ObjectOutputStream.html)에 쓸 수 없습니다. –

0

이 :

java.lang.Exception: java.lang.IllegalArgumentException: can't serialize class com.name.custom.MongoKey 

예외가 발생 MongoKey가 java.io.Serializable을 구현하지 않기 때문에 당신이 열쇠로 Text을 사용할 수 있습니다 예를 들어 키와 지원 클래스의

  • 하나를 사용, .

    클래스 선언에 Serializable을 추가하십시오.

  • 관련 문제