Python 我能';Spark上的--py文件似乎无法正常工作

Python 我能';Spark上的--py文件似乎无法正常工作,python,apache-spark,pyspark,Python,Apache Spark,Pyspark,我在Spark上使用Python时遇到问题。我的应用程序有一些依赖项,如numpy、pandas、astropy等。我无法使用virtualenv创建具有所有依赖项的环境,因为集群上的节点除了HDFS之外没有任何公共挂载点或文件系统。因此,我一直坚持使用spark submit--py文件。我将站点包的内容打包在一个ZIP文件中,并使用--py files=dependencies.ZIP选项提交作业(如中所建议)。然而,集群上的节点似乎仍然看不到内部的模块,它们在导入numpy时抛出类似这样的

我在Spark上使用Python时遇到问题。我的应用程序有一些依赖项,如numpy、pandas、astropy等。我无法使用virtualenv创建具有所有依赖项的环境,因为集群上的节点除了HDFS之外没有任何公共挂载点或文件系统。因此,我一直坚持使用
spark submit--py文件
。我将站点包的内容打包在一个ZIP文件中,并使用
--py files=dependencies.ZIP
选项提交作业(如中所建议)。然而,集群上的节点似乎仍然看不到内部的模块,它们在导入numpy时抛出类似这样的
ImportError

File "/path/anonymized/module.py", line 6, in <module>
    import numpy
File "/tmp/pip-build-4fjFLQ/numpy/numpy/__init__.py", line 180, in <module>   
File "/tmp/pip-build-4fjFLQ/numpy/numpy/add_newdocs.py", line 13, in <module>
File "/tmp/pip-build-4fjFLQ/numpy/numpy/lib/__init__.py", line 8, in <module>
    #
File "/tmp/pip-build-4fjFLQ/numpy/numpy/lib/type_check.py", line 11, in <module>
File "/tmp/pip-build-4fjFLQ/numpy/numpy/core/__init__.py", line 14, in <module>
ImportError: cannot import name multiarray
文件“/path/anonymized/module.py”,第6行,在
进口numpy
文件“/tmp/pip-build-4fjFLQ/numpy/numpy/_init__.py”,第180行,在
文件“/tmp/pip-build-4fjFLQ/numpy/numpy/add_newdocs.py”,第13行,在
文件“/tmp/pip-build-4fjFLQ/numpy/numpy/lib/_init__.py”,第8行,在
#
文件“/tmp/pip-build-4fjFLQ/numpy/numpy/lib/type_check.py”,第11行,在
文件“/tmp/pip-build-4fjFLQ/numpy/numpy/core/_init__.py”,第14行,在
ImportError:无法导入名称多数组
当我切换到virtualenv并使用本地pyspark shell时,一切都很好,所以依赖项都在那里。有人知道是什么导致了这个问题,以及如何解决它吗


谢谢

您可以找到所需的所有.py并相对地添加它们。 有关此说明,请参见:

import os, sys, inspect
 # realpath() will make your script run, even if you symlink it :)
 cmd_folder = os.path.realpath(os.path.abspath(os.path.split(inspect.getfile( inspect.currentframe() ))[0]))
 if cmd_folder not in sys.path:
     sys.path.insert(0, cmd_folder)

 # use this if you want to include modules from a subfolder
 cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],"subfolder")))
 if cmd_subfolder not in sys.path:
     sys.path.insert(0, cmd_subfolder)

 # Info:
 # cmd_folder = os.path.dirname(os.path.abspath(__file__)) # DO NOT USE __file__ !!!
 # __file__ fails if script is called in different ways on Windows
 # __file__ fails if someone does os.chdir() before
 # sys.argv[0] also fails because it doesn't not always contains the path

首先,我假设您的依赖项列在
requirements.txt
中。要打包和压缩依赖项,请在命令行中运行以下命令:

pip install -t dependencies -r requirements.txt
cd dependencies
zip -r ../dependencies.zip .
上面的
cd dependencies
命令对于确保模块位于zip文件的顶层至关重要。谢谢你的提醒

接下来,通过以下方式提交作业:

spark-submit --py-files dependencies.zip spark_job.py
--py files
指令将zip文件发送给Spark workers,但不会将其添加到
PYTHONPATH
(这让我感到困惑)。要将依赖项添加到
PYTHONPATH
以修复
ImportError
,请将以下行添加到Spark作业中,
Spark\u job.py

sc.addPyFile("dependencies.zip")
警告:

假设任何使用商品进行分布式计算的人 硬件必须假定底层硬件可能 由很多种类组成的在客户端机器上构建的Python鸡蛋是特定的 由于所需的C 汇编为复杂的编译包分发一个鸡蛋,如 NumPy、SciPy或pandas是一个容易失败的解决方案 在大多数集群上,至少最终是这样

尽管上述解决方案不能生成卵子,但同样的准则适用。

  • 首先,需要通过--py文件或--files传递文件

    • 当您传递带有上述标志的zip/文件时,基本上您的资源将被传输到在HDFS上创建的临时目录中,该临时目录仅用于该应用程序的生命周期
  • 现在,在代码中,使用以下命令添加这些zip/文件

    sc.addPyFile(“您的zip/文件”)

    • 上面所做的是,它将文件加载到执行环境中,如JVM
  • 现在,使用如下别名在代码中导入zip/文件以开始引用它

    将zip/文件作为别名导入

    注意:导入时不需要使用文件扩展名,如末尾的.py


希望这是有用的。

Spark也会悄悄地无法加载使用python
zipfile
模块创建的zip存档。必须使用Zip实用程序创建Zip存档。

尝试使用
--archives
将anaconda目录存档到每个服务器 并使用
--conf spark.thread.appMasterEnv.PYSPARK\u PYTHON=
告诉spark服务器anaconda目录中的PYTHON执行器路径在哪里

我们的完整配置如下:

--conf spark.yarn.appMasterEnv.PYSPARK_PYTHON=./ANACONDA/anaconda-dependencies/bin/python 

--archives <S3-path>/anaconda-dependencies.zip#ANACONDA
--conf spark.warn.appMasterEnv.PYSPARK_PYTHON=./ANACONDA/ANACONDA依赖项/bin/PYTHON
--归档文件/anaconda dependencies.zip#anaconda

要使这种依赖关系分布方法与编译的扩展一起工作,我们需要做两件事:

  • 在与目标集群相同的操作系统上运行pip安装(最好在集群的主节点上)。这可以确保zip中包含兼容的二进制文件
  • 解压缩目标节点上的存档。这是必要的,因为Python不会从zip文件导入已编译的扩展名。()
  • 使用以下脚本创建依赖项zip将确保您与系统上已安装的任何软件包隔离。这假设virtualenv已安装且当前目录中存在
    requirements.txt
    ,并输出一个
    dependencies.zip
    ,其中包含根级别的所有依赖项

    env_name=temp_env
    #创建虚拟环境
    virtualenv--python=$(哪个python3)--clear/tmp/${env_name}
    #激活虚拟环境
    source/tmp/${env_name}/bin/activate
    #下载并安装依赖项
    pip安装-r requirements.txt
    #将依赖项打包到dependencies.zip中。cd魔法的作用在于,您不能将基本目录指定给zip
    (cd/tmp/${env_name}/lib/python*/site packages/&&zip-r-*)>dependencies.zip
    
    这些依赖项现在可以部署、解压缩并包含在PYTHONPATH中

    spark-submit \
      --master yarn \
      --deploy-mode cluster \
      --conf 'spark.yarn.dist.archives=dependencies.zip#deps' \
      --conf 'spark.yarn.appMasterEnv.PYTHONPATH=deps' \
      --conf 'spark.executorEnv.PYTHONPATH=deps' \
    .
    .
    .
    
    spark.warn.dist.archives=dependencies.zip#deps
    分发zip文件并将其解压缩到名为
    deps

    spark.warn.appMasterEnv.PYTHONPATH=deps
    spark.executorEnv.PYTHONPATH=deps
    在PYTHONPATH中为master和所有worker包含
    deps
    目录

    --部署模式群集
    在集群上运行主执行器,以便它拾取依赖项

    I不