我用scala编写了一个spark作业。我用
spark-shell -i <file-name>
运行这份工作。我需要将命令行参数传递给作业。现在,我通过linux任务调用脚本,我在那里
export INPUT_DATE=2015/04/27
并使用环境变量选项使用:
访问该值System.getenv("INPUT_DATE")
有没有更好的方法来处理Spark-shell中的命令行参数?
答案 0 :(得分:23)
我的解决方案是使用自定义键来定义参数而不是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)
答案 1 :(得分:21)
spark-shell -i <(echo val theDate = $INPUT_DATE ; cat <file-name>)
此解决方案导致在传递给spark-submit
之前在文件开头添加以下行:
val theDate = ...
,
从而定义一个新变量。这样做的方式(<( ... )
语法)称为进程替换。它可以在Bash中使用。有关此问题的更多信息,请参阅this question,有关非Bash环境的替代方案(例如mkFifo
),请参阅。{/ p>
将下面的代码放在脚本中(例如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)
答案 2 :(得分:5)
当我有一个scala脚本时,我使用extraJavaOptions
,这个脚本太简单了,无法通过构建过程,但我仍然需要将参数传递给它。它不漂亮,但它可以工作,你可以快速传递多个参数:
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
,在第四行中,将,
作为分隔符拆分并保存结果到一个数组。然后,您可以访问第五行中的参数。