将命令行参数传递给Spark-shell

时间:2015-04-28 20:12:28

标签: apache-spark

我用scala编写了一个spark作业。我用

spark-shell -i <file-name>

运行这份工作。我需要将命令行参数传递给作业。现在,我通过linux任务调用脚本,我在那里

export INPUT_DATE=2015/04/27 

并使用环境变量选项使用:

访问该值
System.getenv("INPUT_DATE")

有没有更好的方法来处理Spark-shell中的命令行参数?

3 个答案:

答案 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不属于arg1arg2arg3的参数。然后,您可以在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,在第四行中,将,作为分隔符拆分并保存结果到一个数组。然后,您可以访问第五行中的参数。