2013-08-30 10 views
7

szukam małego wyjaśnienia w sprawie odpowiedzi na to pytanie tutaj:Multiple Output pliki do Hadoop Streaming z Pythona Mapper

Generating Separate Output files in Hadoop Streaming

Moje przypadek użycia jest następujący:

mam map-only mapreduce zadanie, które pobiera plik wejściowy, wykonuje wiele analiz i mangi, a następnie zapisuje z powrotem. Jednak niektóre wiersze mogą, ale nie muszą być w niewłaściwym formacie, a jeśli tak jest, chciałbym zapisać oryginalny wiersz w osobnym pliku.

Wygląda na to, że jednym ze sposobów jest dodanie nazwy pliku do drukowanej linii i użycie parametru multipleOutputFormat. Na przykład, gdybym miał pierwotnie:

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

mogłem zamiast zrobić:

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

Jedyny problem mam z tego rozwiązania jest to, że nie chcą nazwa_pliku pojawiać się jako pierwszej kolumnie w plikach tekstowych. Przypuszczam, że mógłbym wtedy uruchomić inną pracę, aby usunąć pierwszą kolumnę każdego pliku, ale wydaje się to trochę głupie. A więc:

1) Czy jest to właściwy sposób zarządzania wieloma plikami wyjściowymi za pomocą zadania Pythona mapreduce?

2) Jaki jest najlepszy sposób na pozbycie się tej początkowej kolumny?

+1

Pytanie jest interesujące. Próbowałem odpowiedzieć. Mam nadzieję, że to ma sens. Proszę, odpowiedz. Dzięki! –

Odpowiedz

16

Możesz zrobić coś podobnego, ale wymaga to trochę kompilacji Java, co, jak sądzę, nie powinno stanowić problemu, jeśli chcesz mimo wszystko zrobić to z Pythonem - Z Pythona, o ile mi wiadomo nie jest możliwe bezpośrednie pominięcie nazwy pliku od końcowego wydruku, ponieważ wymaga tego przypadek użycia w jednym zadaniu. Ale to, co pokazano poniżej, może ułatwić to zadanie!

Oto klasy Java, który jest konieczne skompilowany -

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; 
     } 
} 

Kroki do kompilacji:

  1. Zapisz tekst do pliku dokładnie (nie inna nazwa) CustomMultiOutputFormat.java
  2. Gdy jesteś w katalogu, w którym jest zapisany plik powyżej, typ -

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

  3. Upewnij JAVA_HOME jest ustawiony/ścieżka/do/pliku/SUNJDK przed przystąpieniem powyższe polecenia.

  4. Spersonalizuj.plik jar użyciu (wpisać dokładnie) -

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

  5. Wreszcie uruchomić swoją pracę jak -

    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

Po zrobieniu te powinny być widoczne dwa katalogi wewnątrz outputpath jeden z poprawna_nazwa_pliku i inne z err_file_name. Wszystkie rekordy posiadające valid_file_name jako znacznik trafią do katalogu nazwa_właściwego_pliku, a wszystkie rekordy zawierające err_file_name trafią do katalogu err_file_name.

Mam nadzieję, że to wszystko ma sens.

+1

Miałem nadzieję, że zrobię to w czystym Pythonie za pośrednictwem strumieniowego API [bez definiowania niestandardowego formatu wyjściowego], ale jak powiedziałeś, nie sądzę, że jest to faktycznie możliwe. Dzięki za prawdziwe rozwiązanie! – Justin

+0

Tak, dla Pythona istnieją sposoby, takie jak robienie ostrzału i wykonywanie komendy hadoop, ale nie sądzę, że jest to czysty i dobry sposób robienia tego, co chcesz. –

+0

Co dzieje się z separatorem między kluczem a wartością? Czy linie są już z nią poprzedzone? – slayton

Powiązane problemy