在spark executor节点上安装python依赖关系的最简单方法?

643ylb08  于 2021-07-09  发布在  Spark
关注(0)|答案(1)|浏览(415)

我知道您可以使用pythonspark程序将单个文件作为依赖项发送。但是成熟的图书馆(例如numpy)呢?
spark是否有办法使用提供的包管理器(例如pip)来安装库依赖项?或者在执行spark程序之前必须手动执行吗?
如果答案是手动的,那么在大量分布式节点上同步库(安装路径、版本等)的“最佳实践”方法是什么?

y3bcpkx1

y3bcpkx11#

实际上,我已经试过了,我认为我作为评论发布的链接并不能完全满足您对依赖项的要求。您所要求的是一种让spark在安装依赖项时很好地使用setuptools和pip的方法。在spark中没有更好的支持这一点让我大吃一惊。第三方依赖性问题在通用python中得到了很大程度的解决,但是在spark中,似乎假设您将回到手动依赖性管理之类的方式。
我一直在使用一个不完善但功能强大的基于virtualenv的管道。基本思想是
为你的spark节点创建一个virtualenv
每次你运行一个Spark作业,运行一个新的 pip install 所有的内部python库。如果你已经用 setuptools ,这将安装它们的依赖项
压缩virtualenv的站点包目录。这将包括工作节点需要的库及其依赖项,但不包括它们已经拥有的标准python库
传单曲 .zip 文件,包含库及其依赖项作为 --py-files 当然,您需要编写一些助手脚本来管理这个过程。下面是一个助手脚本,它改编自我一直在使用的脚本,无疑可以改进很多:


# !/usr/bin/env bash

# helper script to fulfil Spark's python packaging requirements.

# Installs everything in a designated virtualenv, then zips up the virtualenv for using as an the value of

# supplied to --py-files argument of `pyspark` or `spark-submit`

# First argument should be the top-level virtualenv

# Second argument is the zipfile which will be created, and

# which you can subsequently supply as the --py-files argument to

# spark-submit

# Subsequent arguments are all the private packages you wish to install

# If these are set up with setuptools, their dependencies will be installed

VENV=$1; shift
ZIPFILE=$1; shift
PACKAGES=$*

. $VENV/bin/activate
for pkg in $PACKAGES; do
  pip install --upgrade $pkg
done
TMPZIP="$TMPDIR/$RANDOM.zip" # abs path. Use random number to avoid clashes with other processes
( cd "$VENV/lib/python2.7/site-packages" && zip -q -r $TMPZIP . )
mv $TMPZIP $ZIPFILE

我有一个其他简单的 Package 器脚本的集合,我运行这些脚本来提交我的spark作业。我只是在该过程中首先调用这个脚本,并确保在运行时将第二个参数(zip文件的名称)作为--py files参数传递 spark-submit (如评论中所述)。我总是运行这些脚本,所以我从不意外地运行旧代码。与spark开销相比,对于我的小规模项目来说,打包开销是最小的。
我们可以做很多改进,例如,在何时创建一个新的zip文件方面非常聪明,将它分成两个zip文件,一个包含经常更改的私有包,另一个包含很少更改的依赖项,这些依赖项不需要经常重建。在重建zip之前,您可以更聪明地检查文件更改。同时检查论点的有效性也是一个好主意。不过,就我的目的而言,这已经足够了。
我提出的解决方案并不是专门为大规模依赖项(比如numpy)设计的(尽管它可能对它们有用)。另外,如果您正在构建基于c的扩展,并且您的驱动程序节点与集群节点具有不同的体系结构,那么它将不起作用。
我在其他地方看到过一些建议,建议在所有节点上运行像anaconda这样的python发行版,因为它已经包含了numpy(和许多其他包),这可能是让numpy以及其他基于c的扩展运行起来的更好方法。无论如何,我们不能总是期望anaconda拥有我们想要的pypi包的正确版本,此外,您可能无法控制spark环境以将anaconda放在其上,因此我认为这种基于virtualenv的方法仍然是有用的。

相关问题