如何通过python软件包来触发作业并使用参数从软件包中调用主文件

use*_*819 6 python apache-spark pyspark

我的python代码结构如下:

Project1
--src
----util.py
----job1.py
----job2.py
--config
----config1.json
----config2.json
Run Code Online (Sandbox Code Playgroud)

我想在spark中运行此job1,但这些我无法调用job1.py,因为它依赖于util.py和job2.py等其他文件和配置文件,因此我需要传递完整的程序包作为spark的输入。

我尝试运行,spark-submit job1.py但是由于诸如job2.py和util.py之类的依赖项对执行者不可用而失败。

根据spark文档,我看到--files是执行此操作的一个选项,但是它可以通过将所有文件名传递给spark-submit来工作,如果将来代码库中的文件数量很多,这看起来很困难。

我看到的另一个选项是使用--archive选项传递代码zip文件,但仍然失败,因为无法引用zip文件。

那么,有人可以建议其他方法在Spark中运行此类代码库吗?

JGC*_*JGC 8

针对您的问题,您需要使用--py-filesPYTHONPATH上应包含的python文件。

我刚遇到一个类似的问题,我想从egg文件中的模块运行模块主要功能。

下面的包装器代码可用于main通过spark-submit的任何模块运行。 为此,您需要使用包和模块名称作为文件名将其放入python文件中。然后,在包装器内部使用文件名来标识要运行的模块。这为执行打包模块提供了更自然的方法,而无需添加额外的参数(这可能会导致混乱)。

这是脚本:

"""
Wrapper script to use when running Python packages via egg file through spark-submit.

Rename this script to the fully qualified package and module name you want to run.
The module should provide a ``main`` function.

Pass any additional arguments to the script.

Usage:

  spark-submit --py-files <LIST-OF-EGGS> <PACKAGE>.<MODULE>.py <MODULE_ARGS>
"""
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()
Run Code Online (Sandbox Code Playgroud)

您无需修改​​任何代码。这都是动态的,并由文件名驱动。

例如,如果将其放入mypackage.mymodule.py并使用spark-submit运行,则包装器将导入mypackage.mymodulemain()在该模块上运行。所有命令行参数均保持不变,并且将被执行的模块自然拾取。

您将需要在命令中包括任何egg文件和其他支持文件。这是一个例子:

spark-submit --py-files mypackage.egg mypackage.mymodule.py --module-arg1 value1
Run Code Online (Sandbox Code Playgroud)


hi-*_*zir 5

有几个基本步骤:

  • 创建一个 Python 包。
  • 构建egg文件或创建一个简单的zip存档。
  • 使用--py-files/将包添加为依赖项pyFiles
  • 创建一个main.py从包中调用函数并将其提交给 Spark 集群的 Thin 。


eir*_*era 1

将其添加到您的PYTHONPATH环境变量中:/path-to-your-spark-directory/python. 另外你的路径变量应该有spark/bin的位置