Добавить банки в Spark Job - spark-submit

Правда... это обсуждалось довольно много.

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

Неопределенные и/или опущенные детали

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

  • Как влияет ClassPath
    • Driver
    • Исполнитель (для выполнения задач)
    • И
    • нет вообще
  • Символ разделения: запятая, двоеточие, точка с запятой
  • Если предоставленные файлы автоматически распределяются
    • для задач (каждому исполнителю)
    • для удаленного драйвера (если он запущен в режиме кластера)
  • принят тип URI: локальный файл, hdfs, http и т.д.
  • Если скопировано в общее место, где это место (hdfs, local?)

Параметры, на которые это влияет:

  • --jars
  • SparkContext.addJar(...) метод
  • SparkContext.addFile(...) метод
  • --conf spark.driver.extraClassPath=... или --driver-class-path ...
  • --conf spark.driver.extraLibraryPath=..., или --driver-library-path ...
  • --conf spark.executor.extraClassPath=...
  • --conf spark.executor.extraLibraryPath=...
  • Не забывайте, что последний параметр spark-submit также является файлом .jar.

Я знаю, где я могу найти основную документацию по искрениям, а именно как отправить, options, а также 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

ClassPath:

КлассPath зависит от того, что вы предоставляете. Есть несколько способов установить что-то в пути к классам:

  • spark.driver.extraClassPath или это псевдоним --driver-class-path, чтобы установить дополнительные пути к классам на node, запускающем драйвер.
  • spark.executor.extraClassPath, чтобы установить дополнительный путь класса на узлах Worker.

Если вы хотите, чтобы определенный JAR выполнялся как на Master, так и на Рабочем, вы должны указать их отдельно в 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"

Распространение файлов:

Это зависит от режима, в котором выполняется ваша работа:

  • Клиентский режим - 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
    
  • Режим кластеров. В режиме кластера в искровом режиме выбран лидер Worker node для выполнения процесса драйвера. Это означает, что задание выполняется не напрямую с мастера node. Здесь Spark не будет устанавливать HTTP-сервер. Вы должны вручную сделать свой JARS доступным для всех рабочих node через HDFS/S3/другие источники, которые доступны для всех узлов.

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

В "Отправка приложений" документация Spark неплохо объясняет принятые префиксы для файлов:

При использовании spark-submit, аппликация вместе с любыми баночками, включенный в параметр --jars, автоматически переносится на кластер. Spark использует следующую схему URL, чтобы стратегии распространения банок:

  • file: - Абсолютные пути и файл:/URI обслуживаются драйверами HTTP файловый сервер, и каждый исполнитель вытаскивает файл из драйвера HTTP сервер.
  • hdfs:, http:, https:, ftp: - эти файлы вниз и JAR из URI, как ожидалось
  • local: - URI, начинающийся с local:/is как ожидается, будет существовать как локальный файл для каждого рабочего node. Это значит, что никакая сетевая IO не будет понесена и хорошо работает для больших файлов /JAR которые нажимаются на каждого рабочего или совместно используются через NFS, GlusterFS и т.д.

Обратите внимание, что JAR и файлы копируются в рабочий каталог для каждого SparkContext на узлах исполнителя.

Как уже отмечалось, JAR копируются в рабочий каталог для каждого рабочего node. Где именно это? Обычно он находится под /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

Поэтому убедитесь, что вы установили эти значения в правильных местах, поэтому вы не будете удивлены, когда приоритет будет приоритетным.

Давайте проанализируем каждый интересующий вопрос:

  • --jars vs SparkContext.addJar: они идентичны, только один из них устанавливается через источник искры и один через код. Выберите ту, которая вам подходит. Важно отметить, что при использовании любой из этих опций не добавляет JAR к пути класса драйвера/исполнителя, вам необходимо явно добавить их с помощью конфигурации extraClassPath на обоих.
  • SparkContext.addJar vs 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. Используйте это, когда вам нужен путь библиотеки, видимый для JVM.

Можно ли предположить, что для простоты я могу добавить дополнительные файлы приложений с использованием трех основных параметров одновременно:

Вы можете смело предположить это только для режима Client, а не для режима Cluster. Как я уже говорил. Кроме того, приведенный вами пример имеет некоторые избыточные аргументы. Например, передача 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

Ответ 2

Другим подходом в spark 2.1.0 является использование --conf spark.driver.userClassPathFirst=true во время spark-submit, который изменяет приоритет загрузки зависимостей и, следовательно, поведение искрового задания, отдавая приоритет банкам, которые пользователь добавляет к классу -path с опцией --jars.

Ответ 3

Существует ограничение на использование --jars: если вы хотите указать каталог для расположения файла jar/xml, он не разрешает расширение каталога. Это означает, что если вам нужно указать абсолютный путь для каждой банки.

Если вы укажете --driver-class-path и будете --driver-class-path в режиме кластера пряжи, то класс драйвера не будет обновлен. Мы можем проверить, обновлен ли путь к классу или нет в интерфейсе spark UI или сервере истории исканий в среде вкладок.

Опция, которая работала для меня, чтобы передать jar, которые содержат расширения каталогов и которые работали в режиме кластера пряжи, была --conf. Лучше передавать пути классов драйверов и исполнителей как --conf, что добавляет их к самому объекту сеанса зажигания, и эти пути отражаются в Spark Configuration. Но, пожалуйста, убедитесь, что файлы jar размещены в одном кластере.

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

Ответ 4

В то время как мы отправляем рабочие задания spark с помощью утилиты spark-submit, существует опция --jars. Используя эту опцию, мы можем передать файл jar приложениям spark.

Ответ 5

Другие настраиваемые параметры Spark, относящиеся к банкам и пути к классам, в случае использования yarn качестве режима развертывания:
Из документации искры,

spark.yarn.jars

List of libraries containing Spark code to distribute to YARN containers.
By default, Spark on YARN will use Spark jars installed locally, but the Spark jars can also be
in a world-readable location on HDFS. This allows YARN to cache it on nodes so that it doesn't
need to be distributed each time an application runs. To point to jars on HDFS, for example,
set this configuration to hdfs:///some/path. Globs are allowed.

spark.yarn.archive

    An archive containing needed Spark jars for distribution to the YARN cache. If set, this
configuration replaces spark.yarn.jars and the archive is used in all the
application containers. The archive should contain jar files in its root directory.
Like with the previous option, the archive can also be hosted on HDFS to speed up file
distribution.

Пользователи могут настроить этот параметр для указания своих jar файлов, которые inturn включается в путь к классу драйвера Spark.