PySpark-Python版本和依赖支持
Package依赖
很多情况下pyspark依赖其他python库/插件/项目,由于odps集群无法自由安装python库,需在本地打包后通过spark-submit上传。对于特定依赖,打包环境需跟线上环境保持一致。我们提供了以下打包方式:
- 不打包直接采用公共资源(无需上传额外资源,只能使用默认提供的python环境)
- 上传单个wheel包(适用于需要的额外python依赖数量较少、较为简单)
- 利用脚本一键生成python环境(基于docker提供当前流行的若干版本的python环境,结合用户提供的requirements文件,利用脚本一键生成完整python包)
- 利用docker容器打包Python环境(可以任意选择python版本,docker容器只是提供了一个linux环境,最终需要把python环境上传到Maxcompute的资源中)
1. 不打包直接采用公共资源
默认提供的python 2.7.13环境配置
spark.hadoop.odps.cupid.resources = public.python-2.7.13-ucs4.tar.gz
spark.pyspark.python = ./public.python-2.7.13-ucs4.tar.gz/python-2.7.13-ucs4/bin/python
三方库List: Here
默认提供的python 3.7.9环境配置
spark.hadoop.odps.cupid.resources = public.python-3.7.9-ucs4.tar.gz
spark.pyspark.python = ./public.python-3.7.9-ucs4.tar.gz/python-3.7.9-ucs4/bin/python3
三方库List: Here
2. 上传单个wheel包
如果依赖较为简单,则可以只上传单个wheel包,通常需要选用manylinux版本,wheel包下载地址:https://pypi.org/
使用方式:
(1)需要将wheel包重命名为zip包,例如将pymysql的wheel包重命名为pymysql.zip
(2)将重命名后的zip包上传(文件类型为archive)
(3)在Dataworks spark节点引用(archive类型)
(4)在代码中修改环境变量后即可import
sys.path.append('pymysql')
import pymysql
3. 利用脚本一键打包
若需要的额外依赖较多,则采取第2个选项上传单个wheel包
会导致重复操作量倍增。因此这里提供一个脚本(下载地址Here),只需提供一个编辑好的requirements文件(格式见Here),就能够直接生成完整的python环境用于PySpark使用,具体如下。
使用
$ chmod +x generate_env_pyspark.sh
$ generate_env_pyspark.sh -h
Usage:
generate_env_pyspark.sh [-p] [-r] [-t] [-c] [-h]
Description:
-p ARG, the version of python, currently supports python 2.7, 3.5, 3.6 and 3.7 versions.
-r ARG, the local path of your python requirements.
-t ARG, the output directory of the gz compressed package.
-c, clean mode, we will only package python according to your requirements, without other pre-provided dependencies.
-h, display help of this script.
示例
# 带有预装依赖的打包方式
$ generate_env_pyspark.sh -p 3.7 -r your_path_to_requirements -t your_output_directory
# 不带预装依赖的打包方式(clean mode)
generate_env_pyspark.sh -p 3.7 -r your_path_to_requirements -t your_output_directory -c
说明
- 脚本适用于Mac/Linux环境,需要预先安装Docker, 见官方文档。
- 目前仅支持python 2.7、3.5、3.6和3.7版本,若对python版本不敏感,当前强烈推荐使用python 3.7。
- -c选项表示是否开启clean mode,clean mode无法使用预装依赖,但输出的python包更小。
- 当前MaxCompute对上传资源的大小有500MB的限制,因此如果大部分预装依赖用不到,强烈推荐使用-c选项打包。
Spark中使用
generate_env_pyspark.sh脚本的输出为在指定目录下(-t选项)生成指定python版本(-p选项)的gz包,以python3.7为例,将生成py37.tar.gz。后续再将此包上传为archieve资源(以odpscmd执行为例,也可用odps-sdk上传,各种方式上传资源参考:资源操作):
# 在odpscmd中执行
add archive /your/path/to/py37.tar.gz -f;
然后在spark配置中增加以下两项配置即可:
spark.hadoop.odps.cupid.resources = your_project.py37.tar.gz
spark.pyspark.python = your_project.py37.tar.gz/bin/python
若上述两个参数不生效,例如用于zeppelin调试pyspark时notebook中的python环境,还需在spark作业中增加以下两项配置:
spark.yarn.appMasterEnv.PYTHONPATH = ./your_project.py37.tar.gz/bin/python
spark.executorEnv.PYTHONPATH = ./your_project.py37.tar.gz/bin/python
4. 利用docker容器打包Python环境
使用条件
(1)需要引入的依赖包含so文件等,无法通过上述zip文件的方式使用 和 无法进行pip install安装
(2)确实对除2.7、3.5、3.6、3.7以外的python版本有特殊需求
针对以上特殊情况,同时保证打包环境与线上环境一致(如mac打出来的python环境与线上环境不兼容),我们基于Docker提供以下步骤进行打包(以Python3.7为例)。
- Docker镜像制作,在安装了docker环境的宿主机新建一个Dockerfile文件,python3参考如下:
python2参考如下:FROM centos:7.6.1810 RUN set -ex \ # 预安装所需组件 && yum install -y wget tar libffi-devel zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make initscripts zip\ && wget https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tgz \ && tar -zxvf Python-3.7.0.tgz \ && cd Python-3.7.0 \ && ./configure prefix=/usr/local/python3 \ && make \ && make install \ && make clean \ && rm -rf /Python-3.7.0* \ && yum install -y epel-release \ && yum install -y python-pip # 设置默认为python3 RUN set -ex \ # 备份旧版本python && mv /usr/bin/python /usr/bin/python27 \ && mv /usr/bin/pip /usr/bin/pip-python27 \ # 配置默认为python3 && ln -s /usr/local/python3/bin/python3.7 /usr/bin/python \ && ln -s /usr/local/python3/bin/pip3 /usr/bin/pip # 修复因修改python版本导致yum失效问题 RUN set -ex \ && sed -i "s#/usr/bin/python#/usr/bin/python27#" /usr/bin/yum \ && sed -i "s#/usr/bin/python#/usr/bin/python27#" /usr/libexec/urlgrabber-ext-down \ && yum install -y deltarpm # 更新pip版本 RUN pip install --upgrade pip
FROM centos:7.6.1810 RUN set -ex \ # 预安装所需组件 && yum install -y wget tar libffi-devel zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make initscripts zip\ && wget https://www.python.org/ftp/python/2.7.18/Python-2.7.18.tgz \ && tar -zxvf Python-2.7.18.tgz \ && cd Python-2.7.18 \ && ./configure prefix=/usr/local/python2 \ && make \ && make install \ && make clean \ && rm -rf /Python-2.7.18* # 设置默认为python RUN set -ex \ && mv /usr/bin/python /usr/bin/python27 \ && ln -s /usr/local/python2/bin/python /usr/bin/python RUN set -ex \ && wget https://bootstrap.pypa.io/get-pip.py \ && python get-pip.py RUN set -ex \ && rm -rf /usr/bin/pip \ && ln -s /usr/local/python2/bin/pip /usr/bin/pip # 修复因修改python版本导致yum失效问题 RUN set -ex \ && sed -i "s#/usr/bin/python#/usr/bin/python27#" /usr/bin/yum \ && sed -i "s#/usr/bin/python#/usr/bin/python27#" /usr/libexec/urlgrabber-ext-down \ && yum install -y deltarpm # 更新pip版本 RUN pip install --upgrade pip
- 构建镜像并运行容器:
# 在Dockerfile文件的目录下运行如下命令: docker build -t python-centos:3.7 . docker run -itd --name python3.7 python-centos:3.7
- 进入容器安装所需的python依赖库:
docker attach python3.7 pip install [所需依赖库]
- 打包python环境:
cd /usr/local/ zip -r python3.7.zip python3/
- 拷贝容器中的python环境到宿主机:
ctrl+P+Q退出容器 在宿主机运行命令:docker cp python3.7:/usr/local/python3.7.zip .
- 上传python3.7.zip包到Maxcompute资源,由于dataworks最大只能上传50MB的包,如果大于50MB可以通过Maxcompute客户端进行上传,上传类型为archive,命令参考资源操作
add archive /path/to/python2.7.tar.gz -f;
- 提交作业时只需要在spark-default.conf或dataworks配置项中添加以下配置即可(spark.hadoop.odps.cupid.resources配置项说明)
spark.hadoop.odps.cupid.resources=[project名].python3.7.zip spark.pyspark.python=./[project名].python3.7.zip/python3/bin/python3.7
注意事项:
``` 通过Docker容器打包,如果遇到so包找不到的情况,则需要手动将so包放到python环境中(一般so包都能在容器中都能找到),并在spark作业中添加以下环境变量:
spark.executorEnv.LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./[project名].python3.7.zip/python3/[创建的so包目录] spark.yarn.appMasterEnv.LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./[project名].python3.7.zip/python3/[创建的so包目录]
## 引用用户自定义的python包
很多情况下用户需要使用自定义的python文件,可以打包提交,这样避免了上传多个py文件,步骤如下:
* 将用户代码打一个zip包,需要在目录下自定义个一个空白的__init__.py
* 将用户代码zip包通过Maxcompute资源上传,并重命名,该资源在工作目录中将会被解压。详见[配置spark.hadoop.odps.cupid.resources](https://github.com/aliyun/MaxCompute-Spark/wiki/07.-Spark%E9%85%8D%E7%BD%AE%E8%AF%A6%E8%A7%A3#maxcompute%E6%95%B0%E6%8D%AE%E4%BA%92%E9%80%9A%E9%85%8D%E7%BD%AE)
* 配置参数:
spark.executorEnv.PYTHONPATH=.
spark.yarn.appMasterEnv.PYTHONPATH=.
* 最后,主python文件就可以import该目录下的python文件了
相关文章
- Django基本命令
Django基本命令 打开linux终端直接在终端中输入以下命令即可。 新建一个django project 命令:django-admin.py startproject project-nam
- 17个新手常见Python运行时错误
17个新手常见Python运行时错误 当初学 Python 时,想要弄懂 Python 的错误信息的含义可能有点复杂。这里列出了常见的的一些让你程序 crash 的运行时错误。 当初学 Python
- Python+SQLite真的有用吗?
SQLite是个很简单的数据库,一个文件就可以搞定,存储上千万行的数据也没问题,图形界面程序有很多,管理很方便,用Python可以编程操作,也很简单,一切都似乎很完美。 我导入了几千万行的数据进SQL
- os各种各样的操作系统接口
这个模块提供了一种使用操作系统相关功能的移动方式。如果您只想读取或写入一个文件,请查看open(),如果您想要操作路径,请参见操作os.path模块,如果您想要读取命令行上所有文件中的所有行,请参阅f
- 通过webpy和nginx-with-fastcgi搭建web.py
这一节讲解的是如何使用Nginx和FastCGI搭建Web.py应用 环境依赖的软件包 Nginx 0.8.* or 0.7.* (需要包含fastcgi和rewrite模块)。 Webpy 0.3
随机推荐
- Django基本命令
Django基本命令 打开linux终端直接在终端中输入以下命令即可。 新建一个django project 命令:django-admin.py startproject project-nam
- 17个新手常见Python运行时错误
17个新手常见Python运行时错误 当初学 Python 时,想要弄懂 Python 的错误信息的含义可能有点复杂。这里列出了常见的的一些让你程序 crash 的运行时错误。 当初学 Python
- Python+SQLite真的有用吗?
SQLite是个很简单的数据库,一个文件就可以搞定,存储上千万行的数据也没问题,图形界面程序有很多,管理很方便,用Python可以编程操作,也很简单,一切都似乎很完美。 我导入了几千万行的数据进SQL
- os各种各样的操作系统接口
这个模块提供了一种使用操作系统相关功能的移动方式。如果您只想读取或写入一个文件,请查看open(),如果您想要操作路径,请参见操作os.path模块,如果您想要读取命令行上所有文件中的所有行,请参阅f
- 通过webpy和nginx-with-fastcgi搭建web.py
这一节讲解的是如何使用Nginx和FastCGI搭建Web.py应用 环境依赖的软件包 Nginx 0.8.* or 0.7.* (需要包含fastcgi和rewrite模块)。 Webpy 0.3