2014-11-27 3 views
0

Мои данные содержат 20 полей в схеме. Для меня важны только первые три поля, насколько это касается программы по сокращению моей карты. Как уменьшить размер ввода для картографа, чтобы получить только первые три поля.Как эффективно уменьшить длину ввода для преобразователя

1,2,3,4,5,6,7,8...20 columns in schema. 
I want only 1,2,3 in the mapper to process it as offset and value. 

Примечание Я не могу использовать PIG как некоторые другие карты снижения логики реализуется в MAP УМЕНЬШИТЬ.

+0

какой api u r используемый - обозначенный или новый? – blackSmith

ответ

0

Вам нужен обычай RecordReader, чтобы сделать это:

public class TrimmedRecordReader implements RecordReader<LongWritable, Text> { 
    private LineRecordReader lineReader; 
    private LongWritable lineKey; 
    private Text lineValue; 

    public TrimmedRecordReader(JobConf job, FileSplit split) throws IOException { 
     lineReader = new LineRecordReader(job, split); 
     lineKey = lineReader.createKey(); 
     lineValue = lineReader.createValue(); 
    } 

    public boolean next(LongWritable key, Text value) throws IOException { 
     if (!lineReader.next(lineKey, lineValue)) { 
      return false; 
     } 

     String[] fields = lineValue.toString().split(","); 
     if (fields.length < 3) { 
      throw new IOException("Invalid record received"); 
     } 
     value.set(fields[0] + "," + fields[1] + "," + fields[2]); 
     return true; 
    } 

    public LongWritable createKey() { 
     return lineReader.createKey(); 
    } 

    public Text createValue() { 
     return lineReader.createValue(); 
    } 

    public long getPos() throws IOException { 
     return lineReader.getPos(); 
    } 

    public void close() throws IOException { 
     lineReader.close(); 
    } 

    public float getProgress() throws IOException { 
     return lineReader.getProgress(); 
    } 
} 

Это должно быть довольно очевидно , просто обернуть LineRecordReader. К сожалению, для его вызова вам необходимо также расширить InputFormat. Достаточно:

public class TrimmedTextInputFormat extends FileInputFormat<LongWritable, Text> { 

    public RecordReader<LongWritable, Text> getRecordReader(InputSplit input, 
    JobConf job, Reporter reporter) throws IOException { 
     reporter.setStatus(input.toString()); 
     return new TrimmedRecordReader(job, (FileSplit) input); 
    } 
} 

Только не забудьте установить его в драйвере.

+0

спасибо blackSmith за код .. Я уже выполнил код и перекрестился с вашей реализацией .. :) –

+0

Так это делает работу, которую вы хотели? Я проверил его успешно. – blackSmith

+0

Я еще не проверял его в производственной среде. Скоро будет обновляться :) –

0

Вы можете реализовать пользовательский формат ввода на карте, чтобы читать только необходимые поля.

Просто для справки, после блоге объясняет, как читать текст абзацами

http://blog.minjar.com/post/54759039969/mapreduce-custom-input-formats-reading

+0

спасибо за статью Vijay. Я попытаюсь реализовать его для моего варианта использования. –

Смежные вопросы