0

我写了一个Spark脚本,依赖于six和各种其他python包。用谷歌云数据喷射器上的spark来管理python依赖关系

$ cat ./test_package/__init__.py 
from six.moves.urllib.request import urlopen 

def download_size(url): 
    return len(urlopen(url).read()) 

因此,我写了一个setup.py,它声明这种依赖关系。

$ cat ./setup.py 
from setuptools import setup 
setup(
    name="Test App", 
    packages=['test_package'], 
    version="0.1", 
    install_requires=['six>=1.0'], 

然后在我的火花剧本,我有要求包装

$ cat spark_script.py 
#!/usr/lib/spark/bin/spark-submit 
from pyspark import SparkContext 
from glob import glob 
from test_package import download_size 

sc = SparkContext() 
sc.addPyFile(glob('dist/Test_App-*.egg')[0]) 

... 

sc.parallelize(urls).map(download_size).collect() 

如果我运行

$ ./test.py 

它工作正常代码。但是,如果我尝试使用python3,

$ PYSPARK_PYTHON=python3 ./test.py 

主节点能够导入test_package,但在映射缩减中间我得到这样每个工作节点上:

File "/hadoop/yarn/nm-local-dir/usercache/sam/appcache/application_1487279780844_0041/container_1487279780844_0041_01_000003/pyspark.zip/pyspark/serializers.py", line 419, in loads 
    return pickle.loads(obj, encoding=encoding) 
    File "./Test_App-0.1-py2.7.egg/test_package/__init__.py", line 2, in <module> 
    from six.moves.urllib.request import urlopen 
ImportError: No module named 'six' 

我如何在Google云数据空间预配置的Apache Spark集群上管理python依赖关系?

回答

1

由于工作任务将在工作节点上运行,并且只能手动安装额外的python包,所以工作节点不具有与主节点相同的可用配置。

您应该使用Dataproc initialization actions在集群部署时在集群的所有节点上运行自定义脚本。对于像PYSPARK_PYTHON这样的环境变量,您可能需要将这些设置附加到/etc/spark/conf/spark-env.sh

+0

“你只是手动安装了你的额外的python包”,但egg文件被添加到'sc.addPyFile(glob('dist/Test_App - *。egg')[0])''和' setup.py'列出了所需的软件包,因此我希望每个工作人员都可以接收,解压并安装egg文件。为什么这只会发生在Python 2? – charmoniumQ

+0

在egg文件中打包python依赖关系是否比在每台机器上运行配置shell脚本更优雅?这似乎是如此。让我知道你是否感觉不同。 – charmoniumQ