2013-08-30 2 views
7

Ищу немного разъяснений по ответам на этот вопрос здесь:Multiple Output Files для Hadoop Streaming с Python Mapper

Generating Separate Output files in Hadoop Streaming

Мой случай использования выглядит следующим образом:

У меня есть задание отображения только для карты, которое принимает входной файл, выполняет много разбора и перебора, а затем записывает обратно. Однако некоторые строки могут быть или не быть в неправильном формате, и если это так, я хотел бы написать оригинальную строку в отдельный файл.

Кажется, что одним из способов сделать это было бы присвоить имя файла строке, которую я печатаю, и использовать параметр multipleOutputFormat. Например, если я изначально имел:

if line_is_valid(line): 
    print name + '\t' + comments 

я мог бы вместо этого сделать:

if line_is_valid(line): 
    print valid_file_name + '\t' + name + '\t' + comments 
else: 
    print err_file_name + '\t' + line 

Единственная проблема у меня с этим решением является то, что я не хочу, чтобы имя_файла появляться в первой колонке в текстовых файлах. Полагаю, я мог бы запустить другую работу, чтобы вырезать первый столбец каждого файла, но это кажется глупым. Итак:

1) Является ли это правильным способом управления несколькими выходными файлами с помощью задания на создание python mapreduce?

2) Каков наилучший способ избавиться от этого начального столбца?

+1

Ваш вопрос интересен. Я попытался ответить. Надеюсь, это имеет смысл. Пожалуйста, ответьте. Благодаря! –

ответ

16

Вы можете сделать что-то вроде следующего, но это связано с небольшим компиляцией Java, который, я думаю, не должен быть проблемой, если вы хотите, чтобы ваш прецедент делался в любом случае с Python- От Python, насколько я знаю невозможно напрямую пропустить имя файла из окончательного вывода, поскольку ваш прецедент требует в одном задании. Но то, что показано ниже, позволяет сделать это с легкостью!

Вот класс Java, который нужно скомпилирован -

package com.custom; 
import org.apache.hadoop.fs.Path; 
import org.apache.hadoop.io.Text; 
import org.apache.hadoop.mapred.lib.MultipleTextOutputFormat; 

public class CustomMultiOutputFormat extends MultipleTextOutputFormat<Text, Text> { 
     /** 
     * Use they key as part of the path for the final output file. 
     */ 
     @Override 
     protected String generateFileNameForKeyValue(Text key, Text value, String leaf) { 
      return new Path(key.toString(), leaf).toString(); 
     } 

     /** 
     * We discard the key as per your requirement 
     */ 
     @Override 
     protected Text generateActualKey(Text key, Text value) { 
      return null; 
     } 
} 

Этапы компиляции:

  1. Сохранить текст в файл точно (не другое имя) CustomMultiOutputFormat.java
  2. Пока вы находитесь в каталоге, где находится вышеуказанный сохраненный файл, введите -

    $JAVA_HOME/bin/javac -cp $(hadoop classpath) -d . CustomMultiOutputFormat.java

  3. Убедитесь, что JAVA_HOME установлен в/путь/к/ваш/SUNJDK перед попыткой выше команды.

  4. Сделайте свой заказ.баночка файл, используя (тип точно) -

    $JAVA_HOME/bin/jar cvf custom.jar com/custom/CustomMultiOutputFormat.class

  5. Наконец, запустить работу, как -

    hadoop jar /path/to/your/hadoop-streaming-*.jar -libjars custom.jar -outputformat com.custom.CustomMultiOutputFormat -file your_script.py -input inputpath --numReduceTasks 0 -output outputpath -mapper your_script.py

После выполнения этого вы должны увидеть две директории внутри OutputPath один с valid_file_name и другие с err_file_name. Все записи, имеющие valid_file_name как тег, перейдут в каталог valid_file_name, и все записи, имеющие имя err_file_name, перейдут в каталог err_file_name.

Надеюсь, все это имеет смысл.

+1

Я надеялся сделать это на чистом питоне через потоковый API [без определения пользовательского формата вывода], но, как вы сказали, я не думаю, что это действительно возможно. Спасибо за реальное решение! – Justin

+0

Да, для Python существуют такие способы, как выполнение обхода и выполнение команды hadoop, но я не думаю, что это чистый и хороший способ делать то, что вы хотите. –

+0

Что происходит с разделителем между ключом и значением? Связаны ли с ним линии? – slayton

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