W wielu rzeczywistych sytuacjach, w których stosujesz MapReduce, ostateczne algorytmy kończą się na kilku krokach MapReduce.
tj. Map1, Reduce1, Map2, Reduce2 i tak dalej.
Mamy więc dane wyjściowe z ostatniej redukcji, które są potrzebne jako dane wejściowe dla następnej mapy.
Dane pośrednie to coś, czego (ogólnie) nie chcesz zachować po pomyślnym zakończeniu potoku. Ponieważ te dane pośrednie są na ogół pewną strukturą danych (jak „mapa” lub „zbiór”), nie chcesz wkładać zbyt wiele wysiłku w pisanie i odczytywanie tych par klucz-wartość.
Jaki jest zalecany sposób robienia tego w Hadoop?
Czy istnieje (prosty) przykład, który pokazuje, jak prawidłowo obsługiwać te dane pośrednie, łącznie z późniejszym czyszczeniem?
Odpowiedzi:
Myślę, że ten samouczek w sieci programistów Yahoo pomoże ci w tym: Chaining Jobs
Używasz
JobClient.runJob()
. Ścieżka wyjściowa danych z pierwszego zadania staje się ścieżką wejściową do drugiego zadania. Muszą one być przekazane jako argumenty do zadań z odpowiednim kodem, aby je przeanalizować i ustawić parametry zadania.Myślę, że powyższa metoda może być jednak sposobem, w jaki zrobił to teraz starszy mapowany interfejs API, ale nadal powinien działać. Podobna metoda będzie dostępna w nowym API mapreduce, ale nie jestem pewien, co to jest.
Jeśli chodzi o usuwanie danych pośrednich po zakończeniu zadania, możesz to zrobić w swoim kodzie. Sposób, w jaki zrobiłem to wcześniej, to użycie czegoś takiego:
Gdzie ścieżka to lokalizacja danych w HDFS. Musisz się upewnić, że usuniesz te dane tylko wtedy, gdy żadne inne zadanie ich nie wymaga.
źródło
Można to zrobić na wiele sposobów.
(1) Praca kaskadowa
Utwórz obiekt JobConf „job1” dla pierwszego zadania i ustaw wszystkie parametry z „input” jako katalogiem wejściowym i „temp” jako katalogiem wyjściowym. Wykonaj to zadanie:
Bezpośrednio pod nim utwórz obiekt JobConf „job2” dla drugiego zadania i ustaw wszystkie parametry z „temp” jako katalogiem wejściowym i „output” jako katalogiem wyjściowym. Wykonaj to zadanie:
(2) Utwórz dwa obiekty JobConf i ustaw w nich wszystkie parametry, tak jak (1), z wyjątkiem tego, że nie używasz JobClient.run.
Następnie utwórz dwa obiekty Job z parametrami jobconfs:
Używając obiektu jobControl, określasz zależności zadań, a następnie uruchamiasz zadania:
(3) Jeśli potrzebujesz struktury podobnej do Map + | Zmniejsz | Map *, możesz użyć klas ChainMapper i ChainReducer, które są dostarczane z usługą Hadoop w wersji 0.19 i nowszych.
źródło
Można to zrobić na wiele sposobów. Skupię się na dwóch.
Jedna to biblioteka adnotacji Riffle ( http://github.com/cwensel/riffle ) do identyfikowania elementów zależnych i „wykonywania” ich w zależności (topologicznej) kolejności.
Lub możesz użyć Cascade (i MapReduceFlow) w Cascading ( http://www.cascading.org/ ). Przyszła wersja będzie obsługiwać adnotacje Riffle, ale teraz działa świetnie z surowymi zadaniami MR JobConf.
Wariantem tego jest nie zarządzanie zadaniami MR ręcznie, ale tworzenie aplikacji przy użyciu Cascading API. Następnie JobConf i łączenie zadań są obsługiwane wewnętrznie za pośrednictwem klas Cascading planner i Flow.
W ten sposób spędzasz czas koncentrując się na swoim problemie, a nie na mechanice zarządzania zadaniami Hadoop itp. Możesz nawet nakładać na siebie różne języki (takie jak clojure lub jruby), aby jeszcze bardziej uprościć programowanie i aplikacje. http://www.cascading.org/modules.html
źródło
Zrobiłem łańcuch pracy używając obiektów JobConf jeden po drugim. Wziąłem WordCount na przykład do łączenia ofert pracy. Jedno zadanie oblicza, ile razy słowo powtórzyło się w danym wyniku. Druga praca przyjmuje wynik pierwszej pracy jako dane wejściowe i oblicza całkowitą liczbę słów w danym wejściu. Poniżej znajduje się kod, który należy umieścić w klasie kierowcy.
Polecenie do uruchomienia tych zadań to:
bin / hadoop jar TotalWords.
Musimy podać ostateczną nazwę zadania dla polecenia. W powyższym przypadku jest to TotalWords.
źródło
Możesz uruchomić łańcuch MR w sposób podany w kodzie.
UWAGA : podano tylko kod kierowcy
KOLEJNOŚĆ TO MAPA
( JOB1 )-> REDUCE-> ( JOB2 ) MAPA Zrobiono
to, aby posortować klucze, ale jest więcej sposobów, takich jak korzystanie z mapy drzewa.
Chcę jednak skupić się na sposobie, w jaki Zlecenia zostały połączone! !
Dziękuję Ci
źródło
Możesz użyć Oozie do przetwarzania Barch zadań MapReduce. http://issues.apache.org/jira/browse/HADOOP-5303
źródło
Istnieją przykłady w projekcie Apache Mahout, które łączą ze sobą wiele zadań MapReduce. Jeden z przykładów można znaleźć pod adresem:
ZalecenieJob.java
http://search-lucene.com/c/Mahout:/core/src/main/java/org/apache/mahout/cf/taste/hadoop/item/RecommenderJob.java%7C%7CRecommenderJob
źródło
Możemy skorzystać z
waitForCompletion(true)
metody Job do zdefiniowania zależności pomiędzy pracą.W moim scenariuszu miałem 3 prace, które były od siebie zależne. W klasie sterownika użyłem poniższego kodu i działa zgodnie z oczekiwaniami.
źródło
Nowa klasa org.apache.hadoop.mapreduce.lib.chain.ChainMapper pomaga w tym scenariuszu
źródło
Chociaż istnieją złożone mechanizmy przepływu pracy Hadoop oparte na serwerze, np. Oozie, mam prostą bibliotekę Java, która umożliwia wykonywanie wielu zadań Hadoop jako przepływu pracy. Konfiguracja zadania i przepływ pracy definiujące zależność między zadaniami są konfigurowane w pliku JSON. Wszystko jest konfigurowalne zewnętrznie i nie wymaga żadnych zmian w istniejącej mapie, aby implementacja była częścią przepływu pracy.
Szczegóły można znaleźć tutaj. Kod źródłowy i jar są dostępne na githubie.
http://pkghosh.wordpress.com/2011/05/22/hadoop-orchestration/
Pranab
źródło
Myślę, że Oozie pomaga kolejnym zadaniom otrzymywać dane wejściowe bezpośrednio z poprzedniej pracy. Pozwala to uniknąć operacji we / wy wykonywanej za pomocą funkcji Jobcontrol.
źródło
Jeśli chcesz programowo łączyć swoje zadania w łańcuchy, zechcesz skorzystać z JobControl. Użycie jest dość proste:
Następnie dodaj wystąpienia ControlledJob. ControlledJob definiuje zadanie z jego zależnościami, w ten sposób automatycznie podłączając wejścia i wyjścia, aby pasowały do „łańcucha” zadań.
uruchamia łańcuch. Będziesz chciał umieścić to w wątku mówionym. Pozwala to sprawdzić stan Twojego łańcucha podczas jego działania:
źródło
Jak wspomniałeś w swoim wymaganiu, że chcesz, aby o / p z MRJob1 było i / p z MRJob2 itd., Możesz rozważyć użycie oozie przepływu pracy w tym przypadku. Możesz również rozważyć zapisanie danych pośrednich do HDFS, ponieważ będą one używane przez następne MRJob. Po zakończeniu zadania możesz wyczyścić dane pośrednie.
źródło