Додайте банки до іскрової роботи - подайте іскру


158

Правда ... це обговорювалося досить багато.

Однак існує багато неоднозначностей і деякі відповіді, що надаються ..., включаючи дублювання посилань jar в конфігурації або параметрах jar / виконавця / драйвера.

Неоднозначні та / або пропущені деталі

Після неоднозначності, незрозумілих та / або пропущених деталей слід уточнити для кожного варіанта:

  • Як впливає ClassPath
    • Водій
    • Виконавець (для виконання завдань)
    • І те й інше
    • зовсім не
  • Характер розділення: кома, двокрапка, крапка з комою
  • Якщо надані файли, вони автоматично розподіляються
    • для виконання завдань (кожному виконавцю)
    • для віддаленого драйвера (якщо він працює в кластерному режимі)
  • тип прийнятого URI: локальний файл, hdfs, http тощо
  • Якщо скопійовано у загальне місце, де це місцезнаходження (hdfs, локальне?)

Варіанти, на які це впливає:

  1. --jars
  2. SparkContext.addJar(...) метод
  3. SparkContext.addFile(...) метод
  4. --conf spark.driver.extraClassPath=... або --driver-class-path ...
  5. --conf spark.driver.extraLibraryPath=..., або --driver-library-path ...
  6. --conf spark.executor.extraClassPath=...
  7. --conf spark.executor.extraLibraryPath=...
  8. не забудьте, останнім параметром іскрової подачі є також .jar файл.

Мені відомо, де я можу знайти основну іскрову документацію , а саме про те, як подати , доступні варіанти , а також JavaDoc . Однак це залишило для мене ще чимало дірок, хоча це також відповіло частково.

Я сподіваюся, що це не все так складно, і що хтось може дати мені чітку і коротку відповідь.

Якби я здогадувався з документації, здається --jars, що SparkContext addJarі addFileметоди, і методи - це ті, які автоматично поширюватимуть файли, в той час як інші параметри просто змінюють ClassPath.

Чи можна було б припустити, що для простоти я можу додати додаткові файли jar програми, використовуючи одночасно 3 основні параметри:

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

Знайшов хорошу статтю про відповідь на іншу публікацію . Однак нічого нового не дізнався. Плакат робить добре зауваження щодо різниці між локальним драйвером (клієнт пряжі) та віддаленим драйвером (кластер нитки). Безумовно важливо пам’ятати.


1
Під яким менеджером кластерів ви працюєте? Автономний / Пряжа / Месо?
Юваль Іцчаков

Будь-який. Я маю на увазі це як уточнення до первинної документації. Я в основному використовую окремий кластер, одиночний примірник, клієнт пряжі, кластер нитки. Інші, можливо, використовують Mesos. Здається, ви зробили кілька хороших оригінальних досліджень у своєму блозі з цього приводу. Я в основному робив те саме, що і ви - використовуючи шейдер, щоб створити банку Uber, щоб спростити процес розгортання.
YoYo

1
Я опублікую відповідь щодо того, як ми розгортаємо Spark Standalone, що може очистити кілька речей.
Юваль Ітчаков

6
Я доклав зусиль, щоб відповісти на всі ваші запитання. Сподіваюся, що це допомагає :)
Ювал Ітчаков

@ Юваль Ітчаков, як і Йойо, про який я згадував, я теж використовую затінену банку, щоб зв'язати всі мої залежності, наприклад, класи класів та інші банки, які я можу використовувати. Я намагаюся зрозуміти, коли я зіткнуся з ситуацією, коли мені потрібно кілька баночок. Я маю на увазі, що я завжди можу скріпити ці кілька баночок в одну банку uber. Чому я не можу продовжувати жити, коли мої затінені банки згуртовують усі мої залежності?
Шила Pancholi

Відповіді:


177

ClassPath:

ClassPath впливає залежно від того, що ви надаєте. Є кілька способів встановити щось на класі:

  • spark.driver.extraClassPathабо це псевдонім, --driver-class-pathщоб встановити додаткові класові шляхи на вузлі, на якому працює драйвер.
  • spark.executor.extraClassPath встановити додатковий шлях до класів на вузлах Worker.

Якщо ви хочете, щоб певний JAR був здійснений як для Майстра, так і для робітника, вам потрібно вказати їх окремо у прапорах BOTH.

Характер розділення:

Дотримуючись тих же правил, що і JVM :

  • Linux: Двокрапка :
    • наприклад: --conf "spark.driver.extraClassPath=/opt/prog/hadoop-aws-2.7.1.jar:/opt/prog/aws-java-sdk-1.10.50.jar"
  • Windows: крапка з комою ;
    • наприклад: --conf "spark.driver.extraClassPath=/opt/prog/hadoop-aws-2.7.1.jar;/opt/prog/aws-java-sdk-1.10.50.jar"

Розподіл файлів:

Це залежить від режиму, під яким ви виконуєте свою роботу:

  1. Клієнтський режим - Spark запускає HTTP-сервер Netty, який розподіляє файли при запуску для кожного з робочих вузлів. Це ви можете бачити, коли ви починаєте роботу Spark:

    16/05/08 17:29:12 INFO HttpFileServer: HTTP File server directory is /tmp/spark-48911afa-db63-4ffc-a298-015e8b96bc55/httpd-84ae312b-5863-4f4c-a1ea-537bfca2bc2b
    16/05/08 17:29:12 INFO HttpServer: Starting HTTP Server
    16/05/08 17:29:12 INFO Utils: Successfully started service 'HTTP file server' on port 58922.
    16/05/08 17:29:12 INFO SparkContext: Added JAR /opt/foo.jar at http://***:58922/jars/com.mycode.jar with timestamp 1462728552732
    16/05/08 17:29:12 INFO SparkContext: Added JAR /opt/aws-java-sdk-1.10.50.jar at http://***:58922/jars/aws-java-sdk-1.10.50.jar with timestamp 1462728552767
  2. Режим кластера - у режимі кластера вибирається іскра «Leader Worker» для запуску процесу драйвера. Це означає, що завдання не виконується безпосередньо з вузла Master. Тут Spark не встановлюватиме HTTP-сервер. Вам потрібно вручну зробити доступними JARS для всіх робочих вузлів через HDFS / S3 / Інші джерела, доступні для всіх вузлів.

Прийнято URI для файлів

У розділі "Надсилання програм" документація Spark добре роз'яснює прийняті префікси для файлів:

При використанні іскрової подачі, jar програми разом з будь-якими банками, що входять до опції --jars, буде автоматично перенесено в кластер. Spark використовує таку схему URL, щоб дозволити різні стратегії розповсюдження банок:

  • Файл: - Абсолютні шляхи та файл: / URI подаються на HTTP-файловий сервер драйвера, і кожен виконавець витягує файл з HTTP-сервера драйвера.
  • hdfs:, http:, https :, ftp: - ці витягаючі файли та JAR з URI, як очікувалося
  • local: - URI, що починається з local: /, як очікується, буде існувати як локальний файл на кожному робочому вузлі. Це означає, що жодного мережевого вводу-виводу не буде здійснено і працює добре для великих файлів / JAR-файлів, які передаються кожному працівнику або передаються через NFS, GlusterFS тощо.

Зауважте, що JAR-файли та файли копіюються у робочий каталог для кожного SparkContext на вузлах виконавця.

Як зазначалося, JAR копіюються в робочий каталог для кожного вузла Worker. Де саме це? Це , як правило , під /var/run/spark/work, ви їх побачите , як це:

drwxr-xr-x    3 spark spark   4096 May 15 06:16 app-20160515061614-0027
drwxr-xr-x    3 spark spark   4096 May 15 07:04 app-20160515070442-0028
drwxr-xr-x    3 spark spark   4096 May 15 07:18 app-20160515071819-0029
drwxr-xr-x    3 spark spark   4096 May 15 07:38 app-20160515073852-0030
drwxr-xr-x    3 spark spark   4096 May 15 08:13 app-20160515081350-0031
drwxr-xr-x    3 spark spark   4096 May 18 17:20 app-20160518172020-0032
drwxr-xr-x    3 spark spark   4096 May 18 17:20 app-20160518172045-0033

І коли ви заглянете всередину, ви побачите всі JAR, розгорнуті разом:

[*@*]$ cd /var/run/spark/work/app-20160508173423-0014/1/
[*@*]$ ll
total 89988
-rwxr-xr-x 1 spark spark   801117 May  8 17:34 awscala_2.10-0.5.5.jar
-rwxr-xr-x 1 spark spark 29558264 May  8 17:34 aws-java-sdk-1.10.50.jar
-rwxr-xr-x 1 spark spark 59466931 May  8 17:34 com.mycode.code.jar
-rwxr-xr-x 1 spark spark  2308517 May  8 17:34 guava-19.0.jar
-rw-r--r-- 1 spark spark      457 May  8 17:34 stderr
-rw-r--r-- 1 spark spark        0 May  8 17:34 stdout

Порушені варіанти:

Найголовніше, що потрібно зрозуміти, - це пріоритет . Якщо ви передасте будь-яку власність за допомогою коду, вона матиме перевагу перед будь-яким параметром, який ви вказали через spark-submit. Про це йдеться в документації Spark:

Будь-які значення, вказані як прапори або у файлі властивостей, будуть передані додатку та об'єднані з тими, які вказані через SparkConf. Властивості, встановлені безпосередньо на SparkConf, мають найвищий пріоритет , потім прапори передаються для іскрової подачі або іскри оболонки, а потім параметри у файлі spark -defaults.conf

Тому переконайтеся, що ви встановили ці значення у відповідних місцях, так що ви не здивуєтесь, коли один має пріоритет над іншим.

Давайте проаналізуємо кожен із питань, про які йдеться:

  • --jarsvs SparkContext.addJar: Вони ідентичні, лише один встановлюється за допомогою іскрової подачі та один за допомогою коду. Виберіть той, який вам найбільше підходить. Важливо відзначити, що використання будь-якого з цих параметрів не додає JAR до вашого драйвера / виконавця classpath , вам потрібно буде чітко додати їх за допомогою extraClassPathконфігурації обох.
  • SparkContext.addJarvs SparkContext.addFile: Використовуйте першу, коли у вас є залежність, яку потрібно використовувати зі своїм кодом. Використовуйте останнє, коли ви просто хочете передати довільний файл навколо своїх робочих вузлів, що не залежить від часу виконання вашого коду.
  • --conf spark.driver.extraClassPath=...або --driver-class-path: Це псевдоніми, неважливо, який з них ви виберете
  • --conf spark.driver.extraLibraryPath=..., or --driver-library-path ... Те саме, що вище, псевдоніми.
  • --conf spark.executor.extraClassPath=...: Використовуйте це, коли у вас є залежність, яка не може бути включена до JAR uber (наприклад, тому, що між версіями бібліотеки існують конфлікти часу компіляції) і яку вам потрібно завантажити під час виконання.
  • --conf spark.executor.extraLibraryPath=...Це передається як java.library.pathопція для СВМ. Використовуйте це, коли вам потрібен шлях до бібліотеки, видимий JVM.

Чи можна було б припустити, що для простоти я можу додати додаткові файли jar програми, використовуючи одночасно 3 основні параметри:

Ви можете сміливо вважати це лише для режиму клієнта, а не для кластерного режиму. Як я вже говорив раніше. Також приклад, який ви навели, має кілька зайвих аргументів. Наприклад, передавати JARs --driver-library-pathмарно, вам потрібно передати їх, extraClassPathякщо ви хочете, щоб вони були на вашому класі. Зрештою, те, що ви хочете зробити, коли розгортаєте зовнішні JAR і на драйвер, і на робочого:

spark-submit --jars additional1.jar,additional2.jar \
  --driver-class-path additional1.jar:additional2.jar \
  --conf spark.executor.extraClassPath=additional1.jar:additional2.jar \
  --class MyClass main-application.jar

4
Чудова і вичерпна відповідь. Дякую. Не могли б ви також розповісти більше про кращі практики розгортання з uber JAR проти залежностей поза JAR (libs у зовнішній папці та вказані у MANIFEST.MFфайлі)?
jsosnowski

2
@jsosnowski Зазвичай, я відмовляюся від використання зовнішніх банок лише тоді, коли є конфлікти, які дуже складно вирішити з моїм JAR uber. Зазвичай я отримую просто за допомогою SBT assemblyMergeStrategyі вибору потрібних мені класів, якщо є конфлікти. Як правило, рекомендую те саме.
Юваль Ітчаков

9
@ yuval-itzchakov Дякую за чудову відповідь, дуже корисна. Один момент я хочу наголосити, щоб допомогти іншим, хто, можливо, допустив таку ж помилку, як я. Аргумент --jars транспортує лише банки до кожної машини в кластері. НЕ вказує іскри використовувати їх у пошуку шляху до класу. Також потрібен шлях -driver-class-шлях (або подібні аргументи або параметри конфігурації). Я спочатку думав, що це альтернативні способи зробити те саме.
Тім Райан

1
@TimRyan Однозначно. Якщо ви подивитесь на останню частину відповіді, я переношу банки як на --jarsпрапор, так і на шлях класу водія / виконавця.
Юваль Ітчаков

1
Врешті-решт я знайшов, як вводити змінні середовища у zeppelin-env.shта додавати --jarsдо них SPARK_SUBMIT_OPTIONS. Це спрацювало. Я використовую формат URI --jars=local:///mnt/dir/file.jar.
Майк

4

Іншим підходом spark 2.1.0є використання --conf spark.driver.userClassPathFirst=trueпід час подачі іскри, що змінює пріоритет завантаження залежностей, а отже, і поведінки іскрового завдання, надаючи пріоритет банкам, які користувач додає до класного шляху з --jarsможливістю.


2
Вам доведеться бути обережними з цим - оскільки це можливо розбити іскру. Це має бути останнім варіантом рішення. Потенційно це може заважати шару, що взаємодіє з пряжею, а також при використанні в режимі «пряжа-клієнт», хоча я не впевнений.
YoYo

Дякую за голову вгору. Чи є спосіб встановити пріоритетність лише 1 банку, який безумовно існує на сервері в старій версії, але ви фізично не можете замінити, і ви знаєте, що не хочете користуватися?
Станіслав

1
Я думаю, у такому випадку ви могли б спробувати саме так, як ви запропонували. Не сказав, що це абсолютно ні. Також майте на увазі, що параметр позначений як "експериментальний" - попередження, яке слід дотримуватися! Не існує безпечного способу визначення пріоритетності однієї версії бібліотеки над іншою. У деяких реалізаціях це вирішується переміщенням однієї з бібліотек в інший простір імен, тому ви можете використовувати обидві версії одночасно.
YoYo

1

Інший варіант конфигурируемого Спарка , що відноситься до баночках і класам, в разі , yarnяк режим розгортання є
З документації іскровий

іскр.ярна.жар

Список бібліотек, що містять іскровий код для поширення в контейнери YARN. За замовчуванням Spark on YARN використовуватиме банки Spark, встановлені локально, але банки Spark також можуть знаходитись у світі, де читається на HDFS. Це дозволяє YARN кешувати його на вузлах, так що його не потрібно поширювати щоразу, коли програма запускається. Наприклад, для вказівки на банки на HDFS, встановіть цю конфігурацію на hdfs: /// some / path. Глобуси дозволені.

іскр.ярна.архів

Архів, що містить необхідні банки Spark для розповсюдження в кеш YARN. Якщо встановлено, ця конфігурація замінює spark.yarn.jars, а архів використовується у всіх контейнерах програми. Архів повинен містити jar файли в його кореневому каталозі. Як і в попередньому варіанті, архів можна розмістити і на HDFS для прискорення розповсюдження файлів.

Користувачі можуть налаштувати цей параметр, щоб вказати свої банки, яка вбудована частина входить у класний шлях драйвера Spark.


1

При використанні іскрової подачі з --master пряжею-кластером, jar програми разом з будь-якими банками, що входять до опції --jars, буде автоматично перенесено в кластер. URL-адреси, надані після --jars, повинні бути розділені комами. Цей список включений у класи водіїв та виконавців

Приклад:

spark-submit - майстер пряжі-кластер --jars ../lib/misc.jar, ../lib/test.jar --клас MainClass MainApp.jar

https://spark.apache.org/docs/latest/submitting-applications.html


0

Існує обмеження на використання --jars: якщо ви хочете вказати каталог для розташування jar/xmlфайлу, він не дозволяє розширювати каталог. Це означає, що вам потрібно вказати абсолютний шлях для кожної банки.

Якщо ви вказуєте --driver-class-pathта виконуєте в режимі кластера пряжі, клас драйверів не оновлюється. Ми можемо перевірити, чи оновлений шлях до класу в інтерфейсі spark або сервер історії іскри в середовищі вкладки.

Варіант, який працював для мене, щоб передати банки, які містять розширення каталогів і які працювали в режимі кластера пряжі, був --confваріантом. Краще пропустити шляхи до класу драйвера та виконавця як --conf, що додає їх до самого об'єкта іскрової сесії, і ці шляхи відображаються на іскровій конфігурації. Але будь-ласка, переконайтеся, що банки ставлять на той самий шлях по кластеру.

spark-submit \
  --master yarn \
  --queue spark_queue \
  --deploy-mode cluster    \
  --num-executors 12 \
  --executor-memory 4g \
  --driver-memory 8g \
  --executor-cores 4 \
  --conf spark.ui.enabled=False \
  --conf spark.driver.extraClassPath=/usr/hdp/current/hbase-master/lib/hbase-server.jar:/usr/hdp/current/hbase-master/lib/hbase-common.jar:/usr/hdp/current/hbase-master/lib/hbase-client.jar:/usr/hdp/current/hbase-master/lib/zookeeper.jar:/usr/hdp/current/hbase-master/lib/hbase-protocol.jar:/usr/hdp/current/spark2-thriftserver/examples/jars/scopt_2.11-3.3.0.jar:/usr/hdp/current/spark2-thriftserver/examples/jars/spark-examples_2.10-1.1.0.jar:/etc/hbase/conf \
  --conf spark.hadoop.mapred.output.dir=/tmp \
  --conf spark.executor.extraClassPath=/usr/hdp/current/hbase-master/lib/hbase-server.jar:/usr/hdp/current/hbase-master/lib/hbase-common.jar:/usr/hdp/current/hbase-master/lib/hbase-client.jar:/usr/hdp/current/hbase-master/lib/zookeeper.jar:/usr/hdp/current/hbase-master/lib/hbase-protocol.jar:/usr/hdp/current/spark2-thriftserver/examples/jars/scopt_2.11-3.3.0.jar:/usr/hdp/current/spark2-thriftserver/examples/jars/spark-examples_2.10-1.1.0.jar:/etc/hbase/conf \
  --conf spark.hadoop.mapreduce.output.fileoutputformat.outputdir=/tmp

Щасливого Нового року!
YoYo

З Новим роком YoYo
Tanveer

0

Поки ми подаємо іскрові завдання за допомогою утиліти для подачі іскри, є варіант --jars. Використовуючи цю опцію, ми можемо передати jar файл для іскрових програм.


Про те, що є такий —jarваріант, було сказано оригінальним плакатом, а також обговорено набагато детальніше більш ніж однією відповіддю. Не здається, що ви надаєте щось нове?
YoYo
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.