2012-11-05 18 views
5

Więc muszę dwa pliki jako dane wejściowe do mojego programu mapreduce: City.dat i Country.datHadoop MapReduce plików Multiple Input

Moim głównym sposobem im analizowania argumenty wiersza polecenia tak:

Path cityInputPath = new Path(args[0]); 
Path countryInputPath = new Path(args[1]); 
Path outputPath = new Path(args[2]); 
MultipleInputs.addInputPath(job, countryInputPath, TextInputFormat.class, JoinCountryMapper.class); 
MultipleInputs.addInputPath(job, cityInputPath, TextInputFormat.class, JoinCityMapper.class); 
FileOutputFormat.setOutputPath(job, outputPath); 

Jeśli mam teraz prowadzę programm za pomocą następującego polecenia:

hadoop jar capital.jar org.myorg.Capital /user/cloudera/capital/input/City.dat /user/cloudera/capital/input/Country.dat /user/cloudera/capital/output 

pojawia się następujący błąd:

Exception in thread "main" org.apache.hadoop.mapred.FileAlreadyExistsException: Output directory /user/cloudera/capital/input/Country.dat already exists 

Dlaczego traktuje to jako mój katalog wyjściowy? Podałem inny katalog jako katalog wyjściowy. Czy ktoś może to wyjaśnić?

+2

Czy możesz zmienić nagłówek pytania, ponieważ dezorientuje on każdego, kto przechodzi przez to pytanie po raz pierwszy. –

Odpowiedz

6

W oparciu o stos, twój katalog wyjściowy nie jest pusty. Więc najprostszą rzeczą jest faktycznie ją usunąć przed uruchomieniem zadania:

bin/hadoop fs -rmr /user/cloudera/capital/output 

Poza tym, twoje argumenty począwszy classname swojej głównej klasie org.myorg.Capital. A więc jest to argument na wskaźniku zero ". (Na podstawie stosu i kodu, który podałeś).

Zasadniczo trzeba przenieść wszystkie swoje indeksów jeden w prawo:

Path cityInputPath = new Path(args[1]); 
Path countryInputPath = new Path(args[2]); 
Path outputPath = new Path(args[3]); 
MultipleInputs.addInputPath(job, countryInputPath, TextInputFormat.class, JoinCountryMapper.class); 
MultipleInputs.addInputPath(job, cityInputPath, TextInputFormat.class, JoinCityMapper.class); 
FileOutputFormat.setOutputPath(job, outputPath); 

Nie zapomnij wyczyścić folder wyjściowy chociaż!

też mała wskazówka dla Ciebie, można oddzielić plików z przecinkiem „” więc można ustawić je za pomocą jednego wywołania takich jak to:

hadoop jar capital.jar org.myorg.Capital /user/cloudera/capital/input/City.dat,/user/cloudera/capital/input/Country.dat 

I w kodzie Java:

FileInputFormat.addInputPaths(job, args[1]); 
+0

To dziwne, ponieważ zawsze uruchamiałem moje programy za pomocą tego polecenia i nigdy nie traktowałem org.myorg.Class jako zerowego argumentu. Przesunięcie wszystkich moich wskaźników dziwnie prowadzi do tego samego błędu. A także mój folder wyjściowy nie istnieje. Problem polega na tym, że uważa, że ​​/user/cloudera/input/Country.dat jest moim folderem wyjściowym ... Dlatego nie jest pusty. Pytanie brzmi, dlaczego uważa, że ​​jest to mój folder wyjściowy. – gaussd

+0

Jeśli prowadzi do dokładnie tego samego błędu, nie uruchamiasz podanego kodu. –

+0

O ile pracowałem z problemami, @gaussd ma rację. org.myorg.Capital nie jest 0. elementem w args. Mówi tylko, że "Zacznij od klasy org.myorg.Capital w pliku capital.jar" .. – pk10

1

Co się tutaj dzieje, to nazwa klasy jest uważana za pierwszy argument!

Domyślnie pierwszym nieoptymalnym argumentem jest nazwa klasy, która ma zostać wywołana. Należy użyć w pełni kwalifikowanej nazwy klasy. Jeśli podano opcję -jar, pierwszym nie-opcyjnym argumentem jest nazwa archiwum JAR zawierającego klasy i źródła danych dla aplikacji, z klasą uruchomienia wskazaną przez nagłówek manifestu klasy głównej.

Co proponuję Ci add a Manifest files to your jar gdzie w tobie określić główną klasę. Pliki MANIFEST.MF może wyglądać następująco:

Manifest-Version: 1.0 
Main-Class: org.myorg.Capital 

A teraz twoja komenda będzie wyglądać następująco:

hadoop jar capital.jar /user/cloudera/capital/input/City.dat /user/cloudera/capital/input/Country.dat /user/cloudera/capital/output 

Można z pewnością wystarczy zmienić wartości indeksu używane w kodzie, ale nie jest to rozwiązanie zalecane.

0

można spróbować to:

Hadoop słoik capital.jar/user/Cloudera/kapitał/input/user/Cloudera/kapitał/wyjścia

To powinno czytać wszystkie pliki w jednym katalogu wejściowego.

Powiązane problemy