2016-04-28 64 views
0

我的作业有多个输入路径。例如:确定块属于Hadoop中的哪个文件路径

//Driver.class 
     for (String s : listFile) { 
      MultipleInputs.addInputPath(job, new Path(s), SequenceFileInputFormat.class);// ex: /home/path1, /home/path2, ... 
     } 
     ..... 
    //Mapper.class 
     public void map(Text key, Data bytes, Context context) throws IOException, InterruptedException { 
       ..... 
      } 

我的问题是有没有办法来确定地图()函数当前对(键,值)属于哪个文件?

+0

您可以从'configure(JobConf)'方法的'JobConf'中提取文件路径。参见javadocs中的示例:https://hadoop.apache.org/docs/r2.6.3/api/org/apache/hadoop/mapred/Mapper.html。 – gudok

回答

0

由于您使用SequenceFileInputFormat为您InputFormatSequenceFileInputFormat使用SequenceFileRecordReader作为其RecordReader并延伸FileInputFormat其方法getSplits()返回拥有该Path,当然还有SequenceFileRecordReader可以得到PathFileSplit。所以你需要做的是当你得到keyvalue使其中一个包含Path,这需要在RecordReader中做。

步骤如下:

  • 创建自定义valClass谁包含original valuepath

    class YourValClass implements Writable { 
        Writable value; // your orginal value 
        Path path; // the path you want 
    } 
    
  • 创建自定义InputFormat类扩展SequenceFileInputFormat和override createRecordReader()方法返回到您的自定义RecordReader

    class YourInputputFormat extends SequenceFileInputFormat<YourKeyClass, YourValClass> { 
    
        @Override 
        public RecordReader<YourKeyClass, YourValClass> createRecordReader(InputSplit split, TaskAttemptContext context) throws IOException { 
         return new YourRecordReader(); // return your custom RecordReader 
        } 
    } 
    
  • 制作自定义RecordReader,在其中你可以结合你的valuepath在一起:

    class YourRecordReader extends SequenceFileRecordReader<YourKeyClass, YourValClass> { 
        Path path; 
    
        @Override 
        public void initialize(InputSplit inputSplit, TaskAttemptContext taskAttemptContext) throws IOException, InterruptedException { 
         super.initialize(inputSplit, taskAttemptContext); 
         FileSplit fileSplit = (FileSplit) inputSplit; 
         this.path = fileSplit.getPath(); // assign the path 
        } 
    
        @Override 
        public YourValClass getCurrentValue() { 
         YourValClass val = super.getCurrentValue(); 
         if (null != val) { 
          val.path = path; // set the path 
         } 
         return val; 
        } 
    } 
    

现在,你可以得到pathYourValClass值。