我可以压缩包含一些 setuptools.Extension 的 PySpark 依赖项吗?

问题描述

我正在尝试通过一个简短的 zip 构建过程 pip install -r requirements.txt -t some_target && cd some_target && zip -r ../deps.zip . && cd .. 为 PySpark (v2.4.3) shell 会话包含 dateparser 包,之后我会,例如,pyspark --py-files deps.zip。但是,当 importing dateparser 时,我从正则表达式库中得到一个间接的 ModuleNotFoundError,抱怨“没有名为‘regex._regex’的模块”(堆栈跟踪说这是在 /mnt/tmp/ spark-some/long/path/deps.zip/regex/_regex_core.py 第 21 行,这当然被 dateparser 引用到堆栈更远的地方)。

我尝试向 requirements.txt 中的 dateparser 行添加一个标志,例如 dateparser --no-binary=regex,但错误仍然存​​在。一个普通的 python shell 能够毫无问题地导入,并且这个 zip 中的其他包似乎可以在 PySpark shell 中毫无问题地导入。这让我陷入了许多兔子洞,但我认为/希望我终于找到了罪魁祸首:即 regex._regex 不是一个普通的 .py 文件,而是一个 .so。我对 python 构建过程的了解有限,但似乎正则表达式库的 setup.py 使用 setuptools.Extension 类将一些 C 文件编译到这个共享对象中。我已经看到 suggestions 修改 LD_LIBRARY_PATH 环境变量以使这些共享对象可被 Python 发现,但许多评论也表明这很危险,而且不是可行的长期解决方案。正常的 python 交互式会话对导入没有问题这一事实也让我持怀疑态度,因为 LD_LIBRARY_PATH 变量甚至不存在于该交互式 shell 中的 os.environ 中。然后我想知道 --py-files 是否不足以包含编译这些 Extension 对象的包(似乎不太可能,因为有很多人在做比我的简单用例更疯狂的事情),或者这是否实际上源于忽略其他一些设置。

谢谢你的任何帮助:)

解决方法

该错误似乎源于导入语句无法识别 zip 存档中的二进制 (.so) 文件,即我使用 --py-files 参数传递的 dependencies.zip。我首先尝试拉出正则表达式依赖项并构建一个 .whl 以包含在 --py-files 中,以发现我的 PySpark (v2.4.3) 版本早于车轮支持。但是,我能够根据源代码构建一个 .egg,然后为 spark.executorEnv 和 spark.driverEnv 设置 PYTHON_EGG_CACHE 和 PYTHON_EGG_DIR 环境变量......不确定其他人是否需要最后一步;它似乎源于奇怪的权限问题,可能只适用于我的用户/组/用例。