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