Wyróżnia się, że MultipleTextOutputFormat nie zostało zmigrowane do nowego interfejsu API. Jeśli więc musimy wybierać katalog wyjściowy i wyjściowy plik na podstawie wartości klucza zapisywanej w locie, to jaka jest alternatywa dla nowego interfejsu API mapreduce?Alternatywa MultipleTextOutputFormat w nowym API
Odpowiedz
Używam AWS EMR Hadoop 1.0.3, i możliwe jest określenie różnych katalogów i plików na podstawie par k/v. Użyj jednej z następujących funkcji z klasy MultipleOutputs
:
public void write(KEYOUT key, VALUEOUT value, String baseOutputPath)
lub
public <K,V> void write(String namedOutput, K key, V value,
String baseOutputPath)
Dawna metoda write
wymaga klucz do być tego samego typu, jak klucz wyjściowego map (w przypadku korzystania z tego w programie odwzorowującym) lub taki sam, jak klawisz zmniejszania wyjścia (w przypadku, gdy używasz go w reduktorze). Wartość należy również wpisać w podobny sposób.
Ten ostatni write
metoda wymaga typy klucz/wartość, aby dopasować typy określona podczas konfiguracji z MultipleObjects statyczne właściwości wykorzystujące addNamedOutput
funkcję:
public static void addNamedOutput(Job job,
String namedOutput,
Class<? extends OutputFormat> outputFormatClass,
Class<?> keyClass,
Class<?> valueClass)
Więc jeśli potrzebujesz różnych typów wyjścia niż Context
korzysta , musisz użyć tej ostatniej metody write
.
Trick do uzyskania różnych katalogach wyjściowych jest zdać baseOutputPath
zawierający separator katalogów, jak poniżej:
multipleOutputs.write("output1", key, value, "dir1/part");
W moim przypadku, to tworzone pliki o nazwie "dir1/part-R-00000".
Nie udało się za pomocą baseOutputPath
zawierającą katalog ..
, więc wszystko baseOutputPath
s są ściśle zawartych w ścieżce przekazany do parametru -output
.
Aby uzyskać więcej informacji na temat konfiguracji i prawidłowego korzystania z opcji MultipleOutputs, zobacz ten kod, który znalazłem (nie mój, ale uznałem, że jest bardzo pomocny, nie używa różnych katalogów wyjściowych). https://github.com/rystsov/learning-hadoop/blob/master/src/main/java/com/twitter/rystsov/mr/MultipulOutputExample.java
podobne do: Hadoop Reducer: How can I output to multiple directories using speculative execution?
W zasadzie można napisać do HDFS bezpośrednio z reduktorem - będziesz tylko trzeba uważać na wykonywanie spekulatywne i wymienić swoje pliki jednoznacznie, następnie trzeba wdrożyć jesteś właścicielem OutputCommitter aby wyczyścić przerwane próby (jest to najtrudniejsza część, jeśli masz naprawdę dynamiczne foldery wyjściowe - będziesz musiał przejść przez każdy folder i usunąć attemps związane z przerwanymi/nieudanymi zadaniami). Prostym rozwiązaniem tego problemu jest wyłączenie spekulacyjnego wykonanie
To nie brzmi prosto: P Dowolne obejście dla MultipleTextOutputFormat? Czy możemy zaimplementować coś takiego jak MultipleTextOutputFormat przy użyciu nowego API? – Amar
Jak stwierdzono w javadoc wielu wyjść dodałem poniższy kod w mojej pracy i reduktorze i działa dobrze. W zadaniu: MultipleOutputs.addNamedOutput (zadanie, nazwaneoutputstring, outputformatclass, keyclass, valueclass); W redukującym: mos = new MultipleOutputs
nie zapomnij o mos.close() w oczyszczeniu(). –
Za najlepszą odpowiedź, skręcić Hadoop. - (str. 253. początkowy) przewodnik 3rd ed
Fragment z książki HDG -
"W starym interfejsie API MapReduce istnieją dwie klasy do generowania wielu wyjść: MultipleOutputFormat i MultipleOutput.W skrócie, MultipleOutputs jest bardziej w pełni funkcjonalny, ale MultipleOutputFormat ma większą kontrolę nad strukturą katalogów wyjściowych i nazewnictwem plików. łączy najlepsze cechy dwóch klas wielu wyjść w starym API. "
Ma przykład, jak kontrolować strukturę katalogów, nazewnictwo plików i format wyjściowy za pomocą interfejsu API MultipleOutputs.
HTH.
Czy MultipleOutput pozwala na określenie nazwy folderu wyjściowego lub nazwy pliku w locie na podstawie par klucz-wartość? Nie sądzę, że jeśli jest jakiś sposób, uprzejmie daj mi znać. – Amar
Tak, koleś i ja nie mogliśmy tego znaleźć! Używając MultipleOutputs możesz pisać tylko do * zestawu * * predefiniowanych * ścieżek plików. Robisz to za pomocą 'MultipleOutputs.addNamedOutput()' w 'run()'. Możliwe, że brakuje mi tu czegoś oprócz rathe, niż składanie takich oświadczeń, jeśli jest to * łatwo znaleźć gdzie indziej *, mógłbyś przynajmniej zamieścić link do niego. – Amar
Mam również wątpliwości, czy użyłeś MultipleTextOutputFormat lub MultipleOutputs! Czytając książkę, wyraźnie stwierdza, tuż przed przykładem: * W porównaniu do MutipleTextOutputFormat istnieje mniejsza kontrola nad nazewnictwem wyjść przy użyciu MultipleOutputs *. – Amar
Zapomniałem wspomnieć, że przetestowałem różnicowanie 'baseOutputPath' na podstawie danych klucz/wartość, i to z powodzeniem wyprowadza do różnych plików. – Eddified
Cieszę się, że o tym wspomniałeś, ale w końcu to odkryłem :) – Amar
Wielkie dzięki za część "dir1/part", nie pomyślałbym o tym! – ssgao