背景
由于需要在公司的大数据平台上使用自己的Python环境,折腾了很久,特此记录
先说几个坑:
- 需要注意版本,不同的spark版本会有些不同,当前我的spark版本是2.2.1,如果以下的方式不生效,记得先看看版本;
- 由于公司平台的环境是离线的,pip down下载的包是需要和硬件架构匹配的,我在mac上pip down的包拿到Linux下是无法正常安装的,建议看一下这篇文章的介绍:https://imshuai.com/python-pip-install-package-offline-tensorflow,里面详细介绍了如果进行离线python环境的移植
- 指定环境和路径是分开的,即使指定了环境,包内部也可能存在依赖丢失的问题
步骤
1. 创建虚拟python环境
这个不多介绍了,不管是通过annaconda还是virtualenv,创建好你自己的python环境。如果你也碰到了离线的平台,建议查看上面的 坑2:自己用docker做一个和服务器一样的系统版本,在上面完成虚拟的环境的创建,再将其拷贝出来;
2. 打包虚拟环境并将其上传hdfs
创建好环境后,进入到环境所在的文件夹,例如你的环境是 ***/***/project_env, cd到project_env下,使用打包命令将当前目录下的文件打包
zip -r project_env.zip ./*
在当前文件夹下,将其上传至hdfs
hadoop fs -put ***/***/project_env/project_env.zip hdfs://***/***/***/env/
3. 使用spark-submit命令引用
client模式下
--conf spark.yarn.dist.archives=hdfs://***/***/***/env/project_env.zip#project_env\
--conf spark.pyspark.driver.python=./project_env/bin/python \
--conf spark.pyspark.python=./project_env/bin/python \
注意 archivs命令后的#是必须的,它指的是将这个zip包解压到的文件夹
cluster模式下,driver端可以略去
--conf spark.yarn.dist.archives=hdfs://***/***/***/env/project_env.zip#project_env\
--conf spark.pyspark.python=./project_env/bin/python \
一般其他的文章到这一步就结束了,但我的还是报错,说pandas的的dependency numpy包不存在,但事实上install pandas时,numpy必定是已经装过的,所以就到处找,应该是环境没有设置
4. python环境设置
除了上述设置后,还需要在代码中显示的指定python的环境,例如下面的测试代码
# test_env.py #
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
from pyspark import SparkContext
os.environ['PYSPARK_PYTHON'] = './project_env/bin/python'
sc = SparkContext(appName="env_test").getOrCreate()
def fun(x):
import pandas
return pandas.__version__
a = sc.parallelize([1,4,5,5,6],3)
print(a.map(lambda x:fun(x)).collect())
如果能输出你安装的pandas是版本,就说明可以正常使用了
补充
也可以在submit的命令中设置这些路径,例如
spark.yarn.dist.archives=hdfs://***/***/***/env/project_env.zip#project_env \
--conf spark.pyspark.python=./project_env/bin/python \
--conf spark.executorEnv.PYSPARK_PYTHON=./project_env/bin/python \
--conf spark.yarn.appMasterEnv.PYSPARK_PYTHON=./project_env/bin/python \
--conf spark.executorEnv.LD_LIBRARY_PATH=/appcom/AnacondaInstall/anaconda3/lib \
最后一个conf是存在在导入一些包的时候报libffi.so.6不存在,这里使用老的的Python环境中的这个依赖。