python - Pyspark 工作人员无法找到 cython 依赖项
问题描述
我正在使用 Cython 对一些 Pyspark 代码进行二进制混淆的项目。我对访问 Cython 依赖项的 spark 工作人员有疑问。
我试图简化项目。这是代码的结构:
├── main.py
├── modules
│ ├── __init__.py
│ ├── toolbox.cpython-38-darwin.so
│ └── toolbox.pyx
├── pyspark_script.cpython-38-darwin.so
├── pyspark_script.pyx
└── setup.py
基本上,我有一个main.py
脚本调用已编译的 pyspark 脚本 ( ),该脚本本身通过高阶函数pyspark_script.cpython-38-darwin.so
从工作人员使用的已编译模块 () 中导入一些函数。modules.toolbox.cpython-38-darwin.so
map
from modules.toolbox import add_one
from modules import toolbox
from modules import product
from pyspark import SparkContext
from pyspark.sql import SQLContext, Row
x = 1
print(f"{x} turns into {toolbox.add_one(x)}")
sc = SparkContext(appName="TestModules")
res_rdd = sc.parallelize(range(0, 10), 3).map(add_one))
print(f"result: {res_rdd.collect()}")
我的问题如下:
- 我使用以下 setup.py 文件对我的 spark 代码和工具箱模块进行 cythonnize:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules = [
Extension("pyspark_script", ["pyspark_script.pyx"]),
Extension("modules.toolbox", ["modules/toolbox.pyx"]),
]
setup(name="Sample Program", cmdclass={"build_ext": build_ext}, ext_modules=ext_modules)
- 我编译依赖项:
$ python setup.py build_ext --inplace
- 我使用以下命令将其提交给 spark:
$ spark-submit --py-files modules/toolbox.cpython-38-darwin.so --master spark://localhost:7077 main.py
- 我有一个错误:工人找不到模块:
21/09/22 18:34:21 WARN TaskSetManager: Lost task 1.0 in stage 1.0 (TID 4) (127.0.0.1 executor 1): org.apache.spark.api.python.PythonException: Traceback (most recent call last):
File "/usr/local/Cellar/apache-spark/3.1.2/libexec/python/lib/pyspark.zip/pyspark/worker.py", line 586, in main
func, profiler, deserializer, serializer = read_command(pickleSer, infile)
File "/usr/local/Cellar/apache-spark/3.1.2/libexec/python/lib/pyspark.zip/pyspark/worker.py", line 69, in read_command
command = serializer._read_with_length(file)
File "/usr/local/Cellar/apache-spark/3.1.2/libexec/python/lib/pyspark.zip/pyspark/serializers.py", line 160, in _read_with_length
return self.loads(obj)
File "/usr/local/Cellar/apache-spark/3.1.2/libexec/python/lib/pyspark.zip/pyspark/serializers.py", line 430, in loads
return pickle.loads(obj, encoding=encoding)
ModuleNotFoundError: No module named 'modules'
at org.apache.spark.api.python.BasePythonRunner$ReaderIterator.handlePythonException(PythonRunner.scala:517)
at org.apache.spark.api.python.PythonRunner$$anon$3.read(PythonRunner.scala:652)
...
我发现了一个绕过这个问题的技巧:我在我的安装文件中删除了对模块路径的引用。这意味着以 开头的第 6 行Extension("modules.toolbox", ...
变为Extension("toolbox", ...
.
Toolbox .so 文件将在项目的根目录中可用,我将其手动移动到modules
目录中:
$ mv toolbox.cpython-38-darwin.so modules
然后工作人员确实找到了工具箱模块,我得到了正确的结果:
1 turns into 2
(...)
result [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] t
21/09/22 18:31:06 INFO SparkUI: Stopped Spark web UI at http://localhost:4040
(...)
所以,我的问题:
- 如果我将设置文件的 Extension() 类中的模块称为“modules.toolbox”,为什么工作人员找不到
Extension("modules.toolbox", ["modules/toolbox.pyx"])
我的工具箱模块 - 即? - 为什么我写作时它会起作用
Extension("toolbox", ["modules/toolbox.pyx"])"
? - 最后为什么master在这两种情况下都找到了模块而不是workers?
更一般地说,如果有人知道主人和工人如何寻找依赖关系并且它们彼此不同,我会非常感激。
解决方案
推荐阅读
- excel-formula - 使用带有通配符的 excel vlookup
- javascript - Magento 2 - 来自 Javascript 的请求返回状态码 302
- kubernetes - 将相关容器托管在节点上,避免网络访问成本
- powershell - 在 Powershell 中替换包含引号的字符串
- c# - 实现静态方法的最佳实践
- teradata - Teradata 以数字格式导出时间结果
- mysql - 如何从不同的列中选择最旧的日期?
- javascript - 实现 UI 后 p5.js 草图不起作用
- python - 如何将python函数传递给接受函数作为参数的cython函数?
- python - 通过仅包含彼此相隔一个月的行来过滤数据框