Передача аргументов командной строки в Spark-shell
У меня есть искорка, написанная на Scala. я использую
spark-shell -i <file-name>
запустить работу. Мне нужно передать аргумент командной строки на работу. Прямо сейчас я вызываю сценарий через задачу Linux, где я делаю
export INPUT_DATE=2015/04/27
и используйте параметр переменной среды для доступа к значению, используя:
System.getenv("INPUT_DATE")
Есть ли лучший способ обработки аргументов командной строки в Spark-shell?
3 ответа
Короткий ответ:
spark-shell -i <(echo val theDate = $INPUT_DATE ; cat <file-name>)
Длинный ответ:
Это решение приводит к добавлению следующей строки в начале файла перед передачей в spark-submit
:
val theDate = ...
,
тем самым определяя новую переменную. Как это делается (<( ... )
синтаксис) называется процессом замещения. Это доступно в Баш. См. Этот вопрос для получения дополнительной информации об этом и для альтернатив (например, mkFifo
) для сред без Bash.
Делая это более систематическим:
Поместите приведенный ниже код в скрипт (например, spark-script.sh
), а затем вы можете просто использовать:
./spark-script.sh your_file.scala first_arg second_arg third_arg
и есть Array[String]
называется args
с вашими аргументами.
Файл spark-script.sh
:
scala_file=$1
shift 1
arguments=$@
#set +o posix # to enable process substitution when not running on bash
spark-shell --master yarn --deploy-mode client \
--queue default \
--driver-memory 2G --executor-memory 4G \
--num-executors 10 \
-i <(echo 'val args = "'$arguments'".split("\\s+")' ; cat $scala_file)
Мое решение - использовать настраиваемый ключ для определения аргументов вместо spark.driver.extraJavaOptions
на случай, если когда-нибудь вы передадите значение, которое может повлиять на поведение JVM.
spark-shell -i your_script.scala --conf spark.driver.args="arg1 arg2 arg3"
Вы можете получить доступ к аргументам из своего кода Scala следующим образом:
val args = sc.getConf.get("spark.driver.args").split("\\s+")
args: Array[String] = Array(arg1, arg2, arg3)
Я использую extraJavaOptions
когда у меня есть скрипт scala, который слишком прост для прохождения процесса сборки, но мне все равно нужно передать ему аргументы. Это не красиво, но работает, и вы можете быстро передать несколько аргументов:
spark-shell -i your_script.scala --conf spark.driver.extraJavaOptions="-Darg1,arg2,arg3"
Обратите внимание, что -D
не относится к аргументам, которые являются arg1
, arg2
, а также arg3
, Затем вы можете получить доступ к аргументам из вашего кода Scala следующим образом:
val sconf = new SparkConf()
val paramsString = sconf.get("spark.driver.extraJavaOptions")
val paramsSlice = paramsString.slice(2,paramsString.length)
val paramsArray = paramsSlice.split(",")
val arg1 = paramsArray(0)
Во второй строке вы загружаете строку, в третьей строке вы обрезаете -D
и в четвертой строке вы разделяете строку ,
в качестве разделителя и сохранить результат в массив. Затем вы можете получить доступ к параметрам, как в пятой строке.