pyspark addPyFile 添加 .py 文件的 zip,但仍未找到模块

Posted

技术标签:

【中文标题】pyspark addPyFile 添加 .py 文件的 zip,但仍未找到模块【英文标题】:pyspark addPyFile to add zip of .py files, but module still not found 【发布时间】:2018-07-20 21:15:32 【问题描述】:

使用 addPyFiles() 似乎不会将所需文件添加到 spark 作业节点(spark 的新手,因此此处可能缺少一些基本的使用知识)。

尝试使用 pyspark 运行脚本并看到某些模块无法导入的错误。以前从未使用过 spark,但其他帖子(来自有问题的包 https://github.com/cerndb/dist-keras/issues/36#issuecomment-378918484 和 https://***.com/a/39779271/8236733)建议压缩模块并通过 sparkContext.addPyFiles(mymodulefiles.zip) 添加到 spark 作业,但仍然出现错误。相关代码sn-ps是...

from distkeras.trainers import *
from distkeras.predictors import *
from distkeras.transformers import *
from distkeras.evaluators import *
from distkeras.utils import *

(我在这里导入的包在https://github.com/cerndb/dist-keras找不到),

conf = SparkConf()
conf.set("spark.app.name", application_name)
conf.set("spark.master", master)  #master='yarn-client'
conf.set("spark.executor.cores", `num_cores`)
conf.set("spark.executor.instances", `num_executors`)
conf.set("spark.locality.wait", "0")
conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer");

if using_spark_2:
    from pyspark.sql import SparkSession

    sc = SparkSession.builder.config(conf=conf) \
            .appName(application_name) \
            .getOrCreate()
    sc.sparkContext.addPyFile("/home/me/Downloads/distkeras.zip") # see https://github.com/cerndb/dist-keras/issues/36#issuecomment-378918484 and https://forums.databricks.com/answers/10207/view.html
    print sc.version

(distkeras.zip 是此目录的压缩文件。:https://github.com/cerndb/dist-keras/tree/master/distkeras),以及

transformer = OneHotTransformer(output_dim=nb_classes, input_col="label_index", output_col="label")
dataset = transformer.transform(dataset)

"""throwing error...
.....
  File "/opt/mapr/spark/spark-2.1.0/python/pyspark/serializers.py", line 458, in loads
    return pickle.loads(obj)
ImportError: No module named distkeras.utils

    at org.apache.spark.api.python.PythonRunner$$anon$1.read(PythonRDD.scala:193)
.....
"""

从我能找到的文档和示例(http://spark.apache.org/docs/2.1.0/api/python/pyspark.html#pyspark.SparkContext.addPyFile 和 https://forums.databricks.com/questions/10193/the-proper-way-to-add-in-dependency-py-files.html)中,上面的代码似乎对我有用(同样,以前从未使用过 spark)。有人知道我在这里做错了什么吗?可以发布对调试有用的更多信息吗?

【问题讨论】:

【参考方案1】:

已修复问题。诚然,解决方案并非完全与火花相关,而是为了其他可能有类似问题的人而发布问题,因为给定的错误消息并没有从一开始就完全清楚我的错误。

TLDR:确保正在加载的 zip 文件的包内容(因此它们应在每个目录中包含一个 __init.py__)按照您的代码预期的方式进行结构化和命名。


我试图通过 zip 加载到 spark 上下文中的包的格式为

mypkg
    file1.py
    file2.py
    subpkg1
        file11.py
    subpkg2
        file21.py

在运行less mypkg.zip 时显示我的 zip

file1.py file2.py subpkg1 subpkg2

所以这里有两件事是错误的。

    没有压缩顶层目录。这是编码期望使用的主要包 未压缩较低级别的目录。

解决了 zip -r mypkg.zip mypkg

更具体地说,必须制作 2 个 zip 文件

    对于 dist-keras 包:

    cd dist-keras; zip -r distkeras.zip distkeras

见https://github.com/cerndb/dist-keras/tree/master/distkeras

    distkeras 使用的 keras 包(未跨集群安装):

    cd keras; zip -r keras.zip keras

见https://github.com/keras-team/keras/tree/master/keras

所以声明 spark session 看起来像

conf = SparkConf()
conf.set("spark.app.name", application_name)
conf.set("spark.master", master)  #master='yarn-client'
conf.set("spark.executor.cores", `num_cores`)
conf.set("spark.executor.instances", `num_executors`)
conf.set("spark.locality.wait", "0")
conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer");

# Check if the user is running Spark 2.0 +
if using_spark_2:
    from pyspark.sql import SparkSession

    sc = SparkSession.builder.config(conf=conf) \
            .appName(application_name) \
            .getOrCreate()
    sc.sparkContext.addPyFile("/home/me/projects/keras-projects/exploring-keras/keras-dist_test/dist-keras/distkeras.zip")
    sc.sparkContext.addPyFile("/home/me/projects/keras-projects/exploring-keras/keras-dist_test/keras/keras.zip")
    print sc.version

【讨论】:

只是想突出显示 ,所以他们应该在每个目录中包含一个 _init.py_。这对我来说是难题的关键部分,我的本地 Python 测试很高兴没有。【参考方案2】:

如果你的模块如下

我的模块\n - 初始化.py -spark1.py -spark2.py

不要进入 myModule 文件夹并添加到 zip。你提到的这个错误。

相反,转到 myModule 文件夹之外。 右键单击并将 myModule 文件夹添加到 zip 并提供另一个名称。

这个想法是当 spark 提取您的 zip 时,应该存在具有相同名称和 hyrarchy 的 myModule 文件夹

【讨论】:

事实证明,“给另一个名字”部分很重要。否则它对我不起作用。

以上是关于pyspark addPyFile 添加 .py 文件的 zip,但仍未找到模块的主要内容,如果未能解决你的问题,请参考以下文章

如何删除或覆盖添加到 pyspark 作业的文件?

将 Jar 添加到独立的 pyspark

使用 spark.sparkContext.addPyFile 导入 Pandas UDF

Ipython 笔记本中的 pyspark 引发 Py4JNetworkError

Pyspark py4j PickleException:“构造 ClassDict 的预期参数为零”

pyspark 导入用户定义的模块或 .py 文件