在 Spark 中的 EMR 上使用 --py-files 从 .zip 文件(使用 zipfile 包在 python 中创建)导入模块时出现问题

Posted

技术标签:

【中文标题】在 Spark 中的 EMR 上使用 --py-files 从 .zip 文件(使用 zipfile 包在 python 中创建)导入模块时出现问题【英文标题】:Problem importing modules from a .zip file (created in python using zipfile package) with --py-files on an EMR in Spark 【发布时间】:2019-04-13 14:11:39 【问题描述】:

我正在尝试将我的应用程序归档到我的测试文件中,以便像这样在 EMR 集群上触发提交:

模块的文件夹结构:

app
--- module1
------ test.py
------ test2.py
--- module2
------ file1.py
------ file2.py

我从测试中调用的 Zip 函数

import zipfile
import os

def zip_deps():
    # make zip

    module1_path = '../module1'
    module2_path = '../module2'
    try:
        with zipfile.ZipFile('deps.zip', 'w', zipfile.ZIP_DEFLATED) as zipf:
            info = zipfile.ZipInfo(module1_path +'/')
            zipf.writestr(info, '')
            for root, dirs, files in os.walk(module1_path):
                for d in dirs:
                    info = zipfile.ZipInfo(os.path.join(root, d)+'/')
                    zipf.writestr(info, '')
                for file in files:
                    zipf.write(os.path.join(root, file),os.path.relpath(os.path.join(root, file)))

            info = zipfile.ZipInfo(module2_path +'/')
            zipf.writestr(info, '')
            for root, dirs, files in os.walk(module2_path):
                for d in dirs:
                    info = zipfile.ZipInfo(os.path.join(root, d)+'/')
                    zipf.writestr(info, '')
                for file in files:
                    zipf.write(os.path.join(root, file),os.path.relpath(os.path.join(root, file)))
    except:
        print('Unexpected error occurred while creating file deps.zip')
    zipf.close()

deps.zip 已正确创建,据我所知,它压缩了我想要的所有文件,并且每个模块文件夹都位于 zip 的基础级别。 实际上,使用以下命令创建的确切 zip: zip -r deps.zip module1 module2 是相同的结构,当我使用

提交它时,这有效
spark-submit --py-files deps.zip driver.py 

来自 EMR 的错误:

Traceback (most recent call last):
  File "driver.py", line 6, in <module>
    from module1.test import test_function
ModuleNotFoundError: No module named 'module1'

FWIW 我还尝试使用带有以下命令的子进程进行压缩,但我在 spark 中的 EMR 上遇到了同样的错误

os.system("zip -r9 deps.zip ../module1")
os.system("zip -r9 deps.zip ../module2")

我不知道为什么在 python 中创建的 zip 文件与在 python 之外创建的 zip 文件不同,但我最近几天一直在研究这个问题,希望有人能提供帮助!

谢谢!!

【问题讨论】:

将工作和不工作的 zip 解压缩到同一件事上? 它们在我看来完全一样,是的。 作为更多参考,我一直在尝试其他 SO 问题 ***.com/questions/39013110/… 不知道区别是不是zipfile.ZIP_DEFLATED 【参考方案1】:

事实证明这是相当简单的事情......

Zipfile 将完整的文件名保存在相对目录中,例如:

../module1/test.py

spark 将文件夹排除在顶层而没有该相对路径,例如:

module1/test.py

我只需要将我的文字改成这样:

with zipfile.ZipFile('deps.zip','w') as zipf:
        for file in file_paths:
            zipf.write(file,os.path.relpath(file,'..'))

如果您提取原始 zip 文件,您将永远不会看到前面带有 ../ 的名称。 耸耸肩

【讨论】:

以上是关于在 Spark 中的 EMR 上使用 --py-files 从 .zip 文件(使用 zipfile 包在 python 中创建)导入模块时出现问题的主要内容,如果未能解决你的问题,请参考以下文章

在 EMR 集群上引导 Spark 3.0.0

Jupyter + EMR + Spark - 从本地机器上的 Jupyter notebook 连接到 EMR 集群

如何使用 EMR 中的引导操作在 spark-conf 中添加 spark.executor.extraClassPath

如何从 Lambda 函数在亚马逊 EMR 上执行 spark 提交?

如何在 EMR 上使用 Spark 3 为 Scala 对象解决“加载类失败”

Spark Dataframe 在 EMR 上加载 500k 文件