To prawda ... dużo o tym dyskutowano.
Istnieje jednak wiele niejasności, a niektóre z udzielonych odpowiedzi ... w tym powielanie odniesień do jar w konfiguracji lub opcjach jars / executor / sterownik.
Niejednoznaczne i / lub pominięte szczegóły
W związku z niejednoznacznością, niejasnymi i / lub pominiętymi szczegółami należy wyjaśnić każdą opcję:
- Jak to wpływa na ClassPath
- Kierowca
- Executor (do zadań w toku)
- Obie
- Ani trochę
- Znak rozdzielający: przecinek, dwukropek, średnik
- Jeśli dostarczone pliki są dystrybuowane automatycznie
- za zadania (do każdego wykonawcy)
- dla zdalnego sterownika (jeśli działał w trybie klastra)
- typ akceptowanego identyfikatora URI: plik lokalny, hdfs, http itp
- W przypadku skopiowania do wspólnej lokalizacji, gdzie ta lokalizacja jest (hdfs, lokalna?)
Opcje, na które ma to wpływ:
--jars
SparkContext.addJar(...)
metodaSparkContext.addFile(...)
metoda--conf spark.driver.extraClassPath=...
lub--driver-class-path ...
--conf spark.driver.extraLibraryPath=...
lub--driver-library-path ...
--conf spark.executor.extraClassPath=...
--conf spark.executor.extraLibraryPath=...
- nie zapominajmy, że ostatnim parametrem funkcji przesyłania iskier jest również plik .jar.
Wiem, gdzie mogę znaleźć główną dokumentację Spark , a konkretnie o sposobie jej przesyłania , dostępnych opcjach , a także JavaDoc . Jednak pozostawiło mi to sporo dziur, chociaż częściowo też odpowiedziało.
Mam nadzieję, że to nie wszystko jest takie skomplikowane i że ktoś udzieli mi jasnej i zwięzłej odpowiedzi.
Gdybym miał zgadywać z dokumentacji, wydaje się --jars
, że metody SparkContext
addJar
i addFile
są tymi, które automatycznie dystrybuują pliki, podczas gdy inne opcje jedynie modyfikują ClassPath.
Czy byłoby bezpiecznie założyć, że dla uproszczenia mogę dodać dodatkowe pliki jar aplikacji, korzystając z 3 głównych opcji w tym samym czasie:
spark-submit --jar additional1.jar,additional2.jar \
--driver-library-path additional1.jar:additional2.jar \
--conf spark.executor.extraLibraryPath=additional1.jar:additional2.jar \
--class MyClass main-application.jar
Znalazłem fajny artykuł na temat odpowiedzi na inny post . Jednak nic nowego się nie nauczyło. Plakat zawiera dobrą uwagę na temat różnicy między sterownikiem lokalnym (klient przędzy) a sterownikiem zdalnym (grupa przędzy). Zdecydowanie ważne, o czym należy pamiętać.
Odpowiedzi:
ClassPath:
ClassPath zależy od tego, co podasz. Istnieje kilka sposobów ustawienia czegoś w ścieżce klas:
spark.driver.extraClassPath
lub jest to alias--driver-class-path
do ustawiania dodatkowych ścieżek klas w węźle, na którym działa sterownik.spark.executor.extraClassPath
aby ustawić dodatkową ścieżkę klas w węzłach Worker.Jeśli chcesz, aby określony plik JAR był wykonywany zarówno na urządzeniu głównym, jak i na robaku, musisz określić je osobno w OBU flagach.
Znak separacji:
Zgodnie z tymi samymi zasadami, co JVM :
:
--conf "spark.driver.extraClassPath=/opt/prog/hadoop-aws-2.7.1.jar:/opt/prog/aws-java-sdk-1.10.50.jar"
;
--conf "spark.driver.extraClassPath=/opt/prog/hadoop-aws-2.7.1.jar;/opt/prog/aws-java-sdk-1.10.50.jar"
Dystrybucja plików:
Zależy to od trybu, w którym wykonujesz swoją pracę:
Tryb klienta - Spark uruchamia serwer HTTP Netty, który dystrybuuje pliki podczas uruchamiania dla każdego węzła roboczego. Możesz zobaczyć, że rozpoczynając pracę w Spark:
Tryb klastra - w trybie klastra Spark wybrał wiodący węzeł Worker, na którym ma wykonać proces sterownika. Oznacza to, że zadanie nie jest uruchamiane bezpośrednio z węzła głównego. Tutaj Spark nie ustawi serwera HTTP. Musisz ręcznie udostępnić pliki JARS dla wszystkich węzłów roboczych za pośrednictwem HDFS / S3 / innych źródeł, które są dostępne dla wszystkich węzłów.
Akceptowane identyfikatory URI dla plików
W sekcji „Przesyłanie wniosków” dokumentacja Spark dobrze radzi sobie z wyjaśnianiem akceptowanych prefiksów plików:
Jak zauważono, pliki JAR są kopiowane do katalogu roboczego dla każdego węzła roboczego . Gdzie to dokładnie jest? Jest to zwykle pod
/var/run/spark/work
zobaczysz je tak:A kiedy zajrzysz do środka, zobaczysz wszystkie wdrożone pliki JAR:
Dotyczy opcji:
Najważniejszą rzeczą do zrozumienia jest priorytet . Jeśli przekażesz jakąkolwiek właściwość za pomocą kodu, będzie ona miała pierwszeństwo przed dowolną opcją określoną za pomocą
spark-submit
. Jest to wspomniane w dokumentacji Spark:Dlatego upewnij się, że ustawiłeś te wartości we właściwych miejscach, aby nie zdziwić się, gdy jedna ma pierwszeństwo przed drugą.
Przeanalizujmy każdą opcję, o której mowa:
--jars
vsSparkContext.addJar
: Są identyczne, tylko jeden jest ustawiany przez przesyłanie iskry, a drugi przez kod. Wybierz ten, który bardziej Ci odpowiada. Jedną ważną rzeczą do zapamiętania jest to, że użycie którejkolwiek z tych opcji nie dodaje pliku JAR do ścieżki klas sterownika / modułu wykonawczego , musisz jawnie dodać je za pomocąextraClassPath
konfiguracji obu.SparkContext.addJar
vsSparkContext.addFile
: Użyj tego pierwszego, gdy masz zależność, która musi być używana z twoim kodem. Użyj tego ostatniego, gdy chcesz po prostu przekazać dowolny plik do węzłów roboczych, co nie jest zależnością czasu wykonywania w kodzie.--conf spark.driver.extraClassPath=...
lub--driver-class-path
: To są aliasy, nie ma znaczenia, który wybierzesz--conf spark.driver.extraLibraryPath=..., or --driver-library-path ...
Jak wyżej, aliasy.--conf spark.executor.extraClassPath=...
: Użyj tego, gdy masz zależność, której nie można dołączyć do pliku JAR typu uber (na przykład z powodu konfliktów czasu kompilacji między wersjami biblioteki) i którą musisz załadować w czasie wykonywania.--conf spark.executor.extraLibraryPath=...
Jest tojava.library.path
opcja dla maszyny JVM. Użyj tego, gdy potrzebujesz ścieżki biblioteki widocznej dla maszyny JVM.Możesz bezpiecznie założyć to tylko w trybie klienta, a nie w trybie klastrowym. Jak powiedziałem wcześniej. Ponadto podany przykład ma kilka zbędnych argumentów. Na przykład przekazywanie plików JAR do
--driver-library-path
jest bezużyteczne, musisz je przekazać,extraClassPath
jeśli chcesz, aby znalazły się na Twojej ścieżce klas. Ostatecznie to, co chcesz zrobić, gdy wdrażasz zewnętrzne pliki JAR zarówno na sterowniku, jak i na pracowniku, to:źródło
MANIFEST.MF
pliku)?assemblyMergeStrategy
i wybierając klasy, których potrzebuję, jeśli występują konflikty. Generalnie polecam to samo.--jars
flagi, jak i ścieżki klasy sterownika / executora.zeppelin-env.sh
i dodawania--jars
doSPARK_SUBMIT_OPTIONS
. To się udało. Format URI, którego używam, to--jars=local:///mnt/dir/file.jar
.Innym podejściem w programie
spark 2.1.0
jest użycie--conf spark.driver.userClassPathFirst=true
podczas wysyłania iskry, co zmienia priorytet obciążenia zależności, a tym samym zachowanie iskry, poprzez nadanie priorytetu jars, które użytkownik dodaje do ścieżki klasy za pomocą--jars
opcji.źródło
Inne konfigurowalne opcje Spark dotyczące słoików i ścieżki klas, w przypadku
yarn
trybu wdrażania, są następująceZ dokumentacji Spark,
Użytkownicy mogą skonfigurować ten parametr, aby określić swoje pliki słoików, które zostaną uwzględnione w ścieżce klas sterownika Spark.
źródło
Podczas korzystania z funkcji spark-submit z --master yarn-cluster, jar aplikacji wraz ze wszystkimi słoikami dołączonymi do opcji --jars zostaną automatycznie przeniesione do klastra. Adresy URL podane po --jars muszą być oddzielone przecinkami. Ta lista jest zawarta w ścieżkach klas sterownika i modułu wykonawczego
Przykład:
spark-submit --master yarn-cluster --jars ../lib/misc.jar, ../lib/test.jar --class MainClass MainApp.jar
https://spark.apache.org/docs/latest/submitting-applications.html
źródło
Istnieje ograniczenie dotyczące używania
--jars
: jeśli chcesz określić katalog dla lokalizacjijar/xml
pliku, nie zezwala na rozszerzenia katalogów. Oznacza to, że musisz określić bezwzględną ścieżkę dla każdego pliku jar.Jeśli określisz
--driver-class-path
i wykonujesz w trybie klastra przędzy, klasa sterownika nie zostanie zaktualizowana. Możemy sprawdzić, czy ścieżka klasy jest aktualizowana, czy nie, w Spark ui lub Spark History Server w środowisku zakładek.Opcją, która działała dla mnie do przekazywania słoików, które zawierają rozszerzenia katalogów i która działała w trybie klastra przędzy, była
--conf
opcja. Lepiej jest przekazywać ścieżki sterownika i klasy wykonawczej jako--conf
, co powoduje dodanie ich do samego obiektu sesji iskrowej, a te ścieżki są odzwierciedlane w konfiguracji platformy Spark. Ale pamiętaj, aby umieścić słoiki na tej samej ścieżce w klastrze.źródło
Chociaż wysyłamy zadania związane z iskrą za pomocą narzędzia do przesyłania iskier, istnieje opcja
--jars
. Korzystając z tej opcji, możemy przekazać plik jar do aplikacji Spark.źródło
—jar
opcja, wspomniał oryginalny plakat, a dodatkowo omówiono ją bardziej szczegółowo w więcej niż jednej odpowiedzi. Nie wygląda na to, że udostępniasz coś nowego?