前阵子需要用到Python相关数据挖掘的包,通过pyspark到线上跑,依赖比如sklearn、pandas等,线上机器版本是centos6.x,python2.6.x,gcc4.4.7,都是比较老的,可能是稳定压倒一切的原则吧,多少年都没更新了,那如何运行指定Python版本并能用线上不具有的包呢。
本文介绍两种方法,一种是通过virtualenv来解决包依赖问题,第二种通过anaconda来解决。不同的是前者需要打包环境和spark 是slave端运行环境一致,第二种就是完全不需要保持与线上spark机环境一致,只需要是linux系统即可。
virtualenv
virtualenv(virtualenv官方文档)是一种可以创建独立python环境的工具。它可以解决程序依赖、版本等环境问题,例如A程序依赖某个库的1.0版本,而B程序有依赖1.1版本,这两个程序要在同一台机器上运行就比较麻烦。这时我们就可以通过 virtualenv为每个程序创建一个独立的不是干扰的虚拟环境来运行。另外,你还可以将创建好的虚拟环境打包,然后将这个环境迁移到其他机器上运行。
因为virtualenv不能做到跨平台,所以建议在与集群机器系统相同的开发机上创建虚拟环境,在windows和mac的虚拟环境可能无法在集群使用。此外对于同一系统的机器不同的版本的c库或者不同位置的c库也会导致虚拟环境无法使用,使用前最好确保迁移机和被迁移机系统版本差不多,比如gcc4.4.7升级后的版本支持c11,但之前版本不支持那就玩完喽
官网是最权威的教材了,想要详细了解的直接点开,下面说一下简单应用。
安装
1
$ [sudo] pip install virtualenv
pip默认使用国外镜像,可以修改下让下载快点
1
2
3
4
5
6
$ vim ~/.pip/pip.conf
添加如下内容
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
[install]
trusted-host=mirrors.aliyun.com
除了清华的源,还有其他: 清华:https://pypi.tuna.tsinghua.edu.cn/simple 阿里云:http://mirrors.aliyun.com/pypi/simple/ 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/ 华中理工大学:http://pypi.hustunique.com/ 山东理工大学:http://pypi.sdutlinux.org/ 豆瓣:http://pypi.douban.com/simple/ 当然python3之前版本默认是没有pip的,推荐按照这个教程安装。
创建虚拟环境
安装好virtualenv后就可以创建虚拟环境了,接下来要创建一个sklearn的虚拟环境:
1
2
3
4
$ virtualenv sklearn_env
New python executable in sklearn_env/bin/python2
Also creating executable in sklearn_env/bin/python
Installing setuptools, pip, wheel...done.
这样我们就在当前目录下创建了一个名为sklearn_env的目录,其中include和lib目录会存放我们要安装库的相关文件。bin目录有启动虚拟环境的相关脚本和这个虚拟环境自己的python和pip. 默认创建的环境是不带有额外装的包的,想要继承现有Python所有依赖包,使用如下命令
1
virtualenv --system-site-packages ENV
该脚本会从/usr/lib/python**/site-packages中复制相应的包,或者其他任何sys.path目录中有site-packages都可以。
激活环境
创建环境后可以通过bin下的脚本来激活环境
1
2
3
4
5
6
7
8
$ source sklearn_env/bin/activate
#启动虚拟环境之前
$ which python
/opt/rh/python27/root/usr/bin/python
(sklearn_env)$ source sklearn_env/bin/activate
#启动虚拟环境之后
(sklearn_env)$ which python
~/sklearn_env/bin/python
然后通过pip直接安装想要的包了,(这里的pip是自己环境包下面的,不是开发机默认的)。 确认无误后,我们需要需要将这个虚拟环境变成可迁移的,这样才能在集群上运行:
1
2
3
4
#将虚拟环境变为可迁移的
(sklearn_env)$ virtualenv --relocatable sklearn_env
#打包便于在集群使用
(sklearn_env)$ zip -r sklearn_env.zip sklearn_env
当然,退出环境对应bin下的deactivate脚本。
anaconda
Anaconda是一个用于科学计算的Python发行版,支持 Linux, Mac, Windows系统,提供了包管理与环境管理的功能,可以很方便地解决多版本python并存、切换以及各种第三方包安装问题。Anaconda利用工具/命令conda来进行package和environment的管理,并且已经包含了Python和相关的配套工具。 这里先解释下conda、anaconda这些概念的差别。conda可以理解为一个工具,也是一个可执行命令,其核心功能是包管理与环境管理。包管理与pip的使用类似,环境管理则允许用户方便地安装不同版本的python并可以快速切换。Anaconda则是一个打包的集合,里面预装好了conda、某个版本的python、众多packages、科学计算工具等等,所以也称为Python的一种发行版。其实还有Miniconda,顾名思义,它只包含最基本的内容——python与conda,以及相关的必须依赖项,对于空间要求严格的用户,Miniconda是一种选择。
conda将几乎所有的工具、第三方包都当做package对待,甚至包括python和conda自身!因此,conda打破了包管理与环境管理的约束,能非常方便地安装各种版本python、各种package并方便地切换。因此对于下载anaconda2.7还是3.4版本都无所谓,因为可以自己通过conda创任意版本的环境。
conda环境管理
关于conda的使用,参考官方教程是最好的,下面简单介绍下,下载并安装完anaconda后,添加其bin目录到系统环境里:
1
2
3
4
5
6
7
8
#安装
bash ~/Downloads/Anaconda2-5.0.1-Linux-x86_64.sh
# 如果安装过程中对“Do you wish the installer to prepend the Anaconda<2 or 3> install location to PATH in your /home/<user>/.bashrc ?”没有选择yes,手工执行下面命令
echo 'export PATH="~/anaconda2/bin:$PATH"' >> ~/.bashrc
# 更新bashrc以立即生效
source ~/.bashrc
# 检验安装是否正确
conda --version
Conda的环境管理功能允许我们同时安装若干不同版本的Python,并能自由切换。对于上述安装过程,假设我们采用的是Python 2.7对应的安装包,那么Python 2.7就是默认的环境(默认名字是root,注意这个root不是超级管理员的意思)。 然后我们安装python3环境,并安装scikit-learn依赖包
1
2
3
4
5
6
## python指定版本,后面是顺带需要安装的包
conda create --name sklearn_env python=3 scikit-learn
## 列出目前创建的坏境
conda info --envs
## 之后不需要这个环境,可以通过下面命令
conda remove --name sklearn_env --all
使用conda安装包常用命令:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 查看当前环境下已安装的包
conda list
# 查看某个指定环境的已安装包
conda list -n sklearn_env
# 查找package信息
conda search numpy
# 安装package
conda install -n sklearn_env numpy
# 如果不用-n指定环境名称,则被安装在当前活跃环境
# 也可以通过-c指定通过某个channel安装
# 更新package
conda update -n sklearn_env numpy
# 删除package
conda remove -n sklearn_env numpy
同样,可以为conda设置国内镜像:
1
2
3
4
5
# 添加Anaconda的TUNA镜像
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
# TUNA的help中镜像地址加有引号,需要去掉
# 设置搜索时显示通道地址
conda config --set show_channel_urls yes
创建环境并安装相应依赖包后,整个环境都已直接迁移了。
环境默认在
下,直接对其打包即可。1
~/anaconda/envs/所装环境名
不同与virtualenv的是,anaconda会把环境所需的c库都放在创建环境名下的lib目录,因此不会出现丢失共享库的错误信息,但如果是从低级机器环境迁移到高级机器环境,并且高级机器环境不可触达(spark集群),高级机器环境下的c库可能得重新在低级机器环境下编译好后放到创建环境名下的lib目录下。
pyspark
在pyspark上用指定的环境运行,在提交作业前加上如下参数即可:
1
2
--archives <环境包地址,最好放在hdfs集群上,免得上传>
--conf spark.yarn.appMasterEnv.PYSPARK_PYTHON=./XX.zip/XX/bin/python
如果是yarn-cluster模式,最好也设置下以下参数:
1
2
spark.yarn.appMasterEnv.PYSPARK_PYTHON = ./XX.zip/XX/bin/python
spark.yarn.appMasterEnv.PYSPARK_DRIVER_PYTHON = ./XX.zip/XX/bin/python
OK,可以放心大胆地跑啦。