如何导入我通过 --py-files 添加到集群的 python 模块?

kin*_*ion 3 import python-import apache-spark pyspark

我有一些想要在应用程序中使用的自定义 jdbc 驱动程序。当我将 Spark 提交到 Kubernetes Spark 集群时,我将这些包含为 --py-files:

spark-submit --py-files s3a://bucket/pyfiles/pyspark_jdbc.zip my_application.py
Run Code Online (Sandbox Code Playgroud)

这给了我:

java.io.FileNotFoundException: File file:/opt/spark/work-dir/pyspark_jdbc.zip does not exist
Run Code Online (Sandbox Code Playgroud)

正如其他答案告诉我的那样,我实际上需要将该 zip 文件添加到 PYTHONPATH 中。现在,我发现至少在 Spark 2.3+ 中不再如此,但让我们这样做:

spark.sparkContext.addPyFile("pyspark_jdbc.zip")
Run Code Online (Sandbox Code Playgroud)

查看集群日志,我看到:

19/10/21 22:40:56 INFO Utils: Fetching s3a://bucket/pyfiles/pyspark_jdbc.zip to 
/var/data/spark-52e390f5-85f4-41c4-9957-ff79f1433f64/spark-402e0a00-6806-40a7-a17d-5adf39a5c2d4/userFiles-680c1bce-ad5f-4a0b-9160-2c3037eefc29/fetchFileTemp5609787392859819321.tmp
Run Code Online (Sandbox Code Playgroud)

因此,pyfiles 肯定被导入,但导入/var/data/...而不是导入我的工作目录。因此,当我将 .zip 文件的位置添加到 python 路径时,我不知道它在哪里。在尝试添加 python 文件之前对集群进行一些诊断:

> print(sys.path)
[..., 
 '/var/data/spark-52e390f5-85f4-41c4-9957-ff79f1433f64/spark-402e0a00-6806-40a7-a17d-5adf39a5c2d4/userFiles-680c1bce-ad5f-4a0b-9160-2c3037eefc29', 
 '/opt/spark/work-dir/s3a', 
 '//bucket/pyfiles/pyspark_jdbc.zip'
...]
> print(os.getcwd())
/opt/spark/work-dir
> subprocess.run(["ls", "-l"])
total 0
Run Code Online (Sandbox Code Playgroud)

所以我们看到 pyspark 确实尝试将s3a://我通过--py-filesPYTHONPATH 添加的文件添加到 PYTHONPATH 中,只是它错误地解释了:并且没有正确添加路径。该/var/data/...目录位于 PYTHONPATH 中,但特定的 .zip 文件不在 PYTHONPATH 中,因此我无法从中导入。

今后我该如何解决这个问题?.zip 文件尚未正确添加到路径中,但在我的程序中,我也不知道

A。pyspark 尝试添加到 PYTHONPATH 的 s3a:// 路径

b. .zip 文件的“var/data/.../ 本地位置”的路径。我知道它在路径中的某个地方,我想我可以解析它,但这会很混乱。

对此有什么优雅的解决方案吗?

kin*_*ion 6

一个(更好的)解决方案是使用 pyspark 中的 SparkFiles 对象来定位您的导入。

from pyspark import SparkFiles

spark.sparkContext.addPyFile(SparkFiles.get("pyspark_jdbc.zp"))
Run Code Online (Sandbox Code Playgroud)