运行 带有附加文件的 YARN 集群上的 Spark 作业

Running Spark jobs on a YARN cluster with additional files

我正在编写一个简单的 spark 应用程序,它使用一些输入 RDD,通过管道将其发送到外部脚本,并将该脚本的输出写入文件。驱动程序代码如下所示:

val input = args(0)
val scriptPath = args(1)
val output = args(2)
val sc = getSparkContext
if (args.length == 4) {
  //Here I pass an additional argument which contains an absolute path to a script on my local machine, only for local testing
  sc.addFile(args(3))
}

sc.textFile(input).pipe(Seq("python2", SparkFiles.get(scriptPath))).saveAsTextFile(output)

当我 运行 它在我的本地机器上时它工作正常。但是当我通过

将它提交到 YARN 集群时
spark-submit --master yarn --deploy-mode cluster --files /absolute/path/to/local/test.py --class somepackage.PythonLauncher path/to/driver.jar path/to/input/part-* test.py path/to/output` 

失败并出现异常。

Lost task 1.0 in stage 0.0 (TID 1, rwds2.1dmp.ru): java.lang.Exception: Subprocess exited with status 2

我尝试了管道命令的不同变体。例如,.pipe("cat") 工作正常,并按预期运行,但 .pipe(Seq("cat", scriptPath)) 也失败,错误代码为 1,因此似乎 spark 无法找出集群节点上脚本的路径。

有什么建议吗?

我自己不使用 python 但我发现一些线索可能对你有用(在 Spark-1.3 SparkSubmitArguments 的源代码中)

  • --py-files PY_FILES, 逗号分隔的 .zip、.egg 或 .py 文件列表Python 个应用程序的 PYTHONPATH。

  • --files FILES, 要放置在每个执行程序的工作目录中的文件的逗号分隔列表。

  • --archives ARCHIVES, 要提取到每个执行程序的工作目录中的逗号分隔的存档列表。

此外,您对 spark-submit 的论点应遵循以下样式:

Usage: spark-submit [options] <app jar | python file> [app arguments]

您可能想尝试使用 local://$SPARK_YARN_STAGING_DIR 环境变量。

例如,以下应该有效:

spark-submit \
    --master yarn \
    --deploy-mode cluster \
    --files /absolute/path/to/local/test.py \
    --class somepackage.PythonLauncher \
    local://$SPARK_YARN_STAGING_DIR/test.py

要理解为什么,你必须熟悉spark的三种运行ning模式的区别,例如。独立、纱线客户端、纱线集群。

与独立和 yarn-client 一样,驱动程序 运行 位于本地计算机的当前位置,而工作程序 运行 位于其他位置(独立可能是 $[= 下的另一个临时目录17=], yarn-client 可能是集群中的一个随机节点), 所以你可以通过驱动程序中指定的本地路径访问本地文件,而在工作程序中则不能。

然而,当你 运行 使用 yarn-cluster 模式时,你的驱动程序和工作程序 运行 在一个随机的集群节点上,本地文件是相对于它们的工作机器和目录的,因此文件未找到异常抛出,您需要在提交时使用 --files 或 --archive 存档这些文件,或者在提交前自己将它们存档在 .egg 或 .jar 中,或者在您的文件中使用 addFile api像 .

这样的驱动程序