在AWS EMR上的zip文件中提交pyspark应用

时间:2019-05-27 11:45:41

标签: python apache-spark amazon-emr

我们有一个pyspark-jobs存储库,其中包含在构建过​​程中将S3中的zip工件推送到该库之后。假设有一个这样的工作是find-homes.zip,其内容如下所示:

find-homes.zip
+-find_homes
  +- __init__.py
  +- run.py
+-helpers
  +- __init__.py
  +- helper_mod.py

我需要将zip内部的run.py(依赖于助手)执行为主程序。我正在客户端模式下运行作业,而我尝试的命令是spark-submit --py-files find-homes.zip find_homes.run.pyfind_homes.run.py文件是一个精简包装,包含以下代码:

import os
import importlib

def main():
    filename = os.path.basename(__file__)
    module = os.path.splitext(filename)[0]
    module = importlib.import_module(module)
    module.main()


if __name__ == '__main__':
    main()

我基本上遵循this SO线程的建议,但是没有任何效果。启动作业后显示的错误是:

Traceback (most recent call last):
  File "/home/hadoop/find_homes.run.py", line 13, in <module>
    main()
  File "/home/hadoop/find_homes.run.py", line 8, in main
    module = importlib.import_module(module)
  File "/usr/lib64/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 941, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 953, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'find_homes'

发现我在这里想念的是什么我失去了耐心。这些建议(包括使用zip位置更新PYTHONPATH)均不起作用,因此,非常感谢您提供任何帮助,甚至向正确方向轻推。我针对EMR v5.23.0使用Spark 2.4

更新

好吧,发生了一件奇怪的事。我正在使用以下gradle任务来生成zip:

task build(type: Zip) {
    from ('src/')
    into "."
    archiveName = "${project.name}.zip"
    includeEmptyDirs = false
    destinationDir new File(projectDir, 'build/distributions') 
}

我不知道这是怎么发生的,但是我只是解压缩了工件,然后再次使用zip -r find_homes.zip <packages>对其进行了压缩,然后将生成的zip与spark-submit一起使用,并且可以正常工作。不知道为什么,因为两种情况下的文件夹结构都完全相同。

1 个答案:

答案 0 :(得分:0)

对于那些使用EMR从事火花工作的人,我将分享我的发现和尝试不同方法后的做法。关键点列表如下。

  1. 通过EMR引导脚本管理Python依赖项。您依赖的所有python软件包都必须安装在执行程序上(例如pandas,sklearn等)。可以在启动集群时通过此引导脚本完成此操作。

  2. 假设您有一个针对Python(可能与Java等其他语言一起使用)的gradle项目,那么如果处理好用例#1,pygradle似乎并不会增加太多价值。

  3. 内置的gradle zip任务对于使用Python模块创建zip文件不太可能起作用。我使用Python添加了一个zip创建模块,并通过命令行执行在gradle任务中调用了该模块。因此,gradle任务使用适当的参数调用python脚本以生成zip文件。确保您的软件包位于zip的根目录下。然后点击我在上面的问题中分享的链接,以提交您的pyspark作业。