带有 --files 参数错误的 PySpark spark-submit 命令

PySpark spark-submit command with --files argument Error

我是 运行 Spark 2.3 集群中的 PySpark 作业,使用以下命令。

spark-submit 
--deploy-mode cluster 
--master yarn 
--files ETLConfig.json 
PySpark_ETL_Job_v0.2.py

ETLConfig.json 有一个参数传递给 PySpark 脚本。我在主块中引用此配置 json 文件,如下所示:

configFilePath = os.path.join(SparkFiles.getRootDirectory(), 'ETLConfig.json')
with open(configFilePath, 'r') as configFile:
    configDict = json.load(configFile)

但是,该命令抛出以下错误。

No such file or directory: u'/tmp/spark-7dbe9acd-8b02-403a-987d-3accfc881a98/userFiles-4df4-5460-bd9c-4946-b289-6433-drgs/ETLConfig.json'

我可以知道我的脚本有什么问题吗?我也尝试使用 SparkFiles.get() 命令,但它也没有用。

您使用 cluster 部署模式。在这种情况下,--files 路径不是指您用于提交的机器上的本地路径,而是指用于生成驱动程序的工作程序上的本地路径,它是集群中的任意节点。

如果您想使用集群模式分发文件,您应该将这些文件存储在每个节点都可以访问的存储中。例如,您可以使用:

  • HTTP/HTTPS URL.
  • HDFS URL.

您应该可以从 运行 驱动程序中的 PWD 加载它。 Yarn 将在 --files 将转储文件的文件夹中启动主容器进程。对于客户端模式会有所不同,但对于集群模式它应该可以正常工作。例如,这对我有用:

driver.py

from pyspark import SparkContext, SparkFiles
import os

with SparkContext() as sc:
    print "PWD: " + os.getcwd()
    print "SparkFiles: " + SparkFiles.getRootDirectory()
    data = open('data.json')
    print "Success!"

火花提交

spark-submit --deploy-mode cluster --master yarn --files data.json driver.py

已更新(比较路径):

我更新了代码以打印 PWD(有效)和 SparkFiles.getRootDirectory(无效)。由于某种原因,路径不同。我不确定为什么会这样……但是直接从 PWD 加载文件是我从驱动程序访问文件时一直做的事情。

这是打印的路径:

PWD: /var/lib/hadoop-yarn/cache/yarn/nm-local-dir/usercache/rwidmaier/appcache/application_1539970334177_0004/container_1539970334177_0004_01_000001
SparkFiles: /var/lib/hadoop-yarn/cache/yarn/nm-local-dir/usercache/rwidmaier/appcache/application_1539970334177_0004/spark-e869ac40-66b4-427e-a928-deef73b34e40/userFiles-a1d8e17f-b8a5-4999-8

更新 #2

显然,它的工作方式是--files,它的兄弟们只保证在Executors 上提供SparkFiles.get(..) 文件夹中的文件,而不是在Driver 上。但是,为了将它们发送给执行程序,Spark 首先将它们下载到驱动程序上的 PWD,这样您就可以从那里访问它。

它实际上只提到了帮助文本中的执行程序,而不是驱动程序。

  --files FILES               Comma-separated list of files to be placed in the working
                              directory of each executor. File paths of these files
                              in executors can be accessed via SparkFiles.get(fileName).

作为参考,here 是将文件下载到驱动程序的位置。