在開發Pyspark代碼時,經常會用到Python的依賴包。在PySpark的分佈式運行的環境下,要確保所有節點均存在我們用到的Packages,本篇文章主要介紹如何將我們需要的Package依賴包加載到我們的運行環境中,而非將全量的Package包加載到Pyspark運行環境中,本篇文章以xgboost1.0.2包爲例來介紹。
測試環境:
1.Redhat7.6
2.CDH5.16.2
3.使用root用戶操作
1.確保集羣所有節點已安裝了相同的Python版本,測試環境使用了Anaconda來部署統一的Python環境。
2.找一個任意OS節點裝上Python3.6.4+版本,用來準備提取依賴包
配置pip使用國內的Python源
[root@cdh02 ~]# cat /etc/pip.conf
[global]
index-url = https://mirrors.aliyun.com/pypi/simple/
[install]
user = true
trusted-host=mirrors.aliyun.com
3.在上一步的節點上安裝xgboost1.0.2依賴包
/opt/cloudera/parcels/Anaconda-5.1.0.1/bin/pip install xgboost==1.0.2
xgboost包安裝成功後默認在/root/.local/lib/python3.7/site-packages目錄下
驗證xgboost包是否安裝安裝成功
4.將安裝成功的xgboost包打包成zip並上傳到hdfs目錄
cd /root/.local/lib/python3.6/site-packages/
zip -r xgb.zip xgboost
將準備好的xgb.zip包上傳到hdfs的/python/dependency/目錄下
hadoop fs -mkdir -p /python/dependency
hadoop fs -put xgb.zip /python/dependency/
hadoop fs -ls /python/dependency
1.在初始化SparkSession對象時指定spark.yarn.dist.archives參數
spark = SparkSession\
.builder\
.appName("PythonPi")\
.config('spark.yarn.dist.archives', 'hdfs:///python/dependency/xgb.zip#xgb')\
.getOrCreate()
注意:指定的路徑是HDFS上的路徑,路徑後的#xgb是必須指定的,xgb可以任意命令,需要和後面代碼使用一致即可。
2.自定義一個函數,主要用來加載Python的環境變量(在執行分佈式代碼時需要調用該函數,否則Executor的運行環境不會加載Python依賴)
def fun(x):
import sys
import os
sys.path.append(os.getcwd() + "/" + "xgb")
import xgboost
return xgboost.__version__
3.接下來就是在代碼中使用定義的function
sc = spark.sparkContext
rdd = sc.parallelize([1,2,3,4,5,6,7], 3)
rdd.map(lambda x: fun(x)).distinct().collect()
4.通過上述的方式在執行Executor時加載Python的依賴包到運行環境中解決Pyspark對Packages依賴問題,完整示例代碼如下:
from __future__ import print_function
import sys
from random import random
from operator import add
from pyspark.sql import SparkSession
import os
py_environ=os.environ['CONDA_DEFAULT_ENV']
if py_environ=='python2.7':
os.environ['PYSPARK_PYTHON'] = '/usr/bin/python'
else:
os.environ['PYSPARK_PYTHON'] = '/opt/cloudera/parcels/Anaconda-5.1.0.1/bin/python'
spark = SparkSession\
.builder\
.appName("PythonPi")\
.config('spark.yarn.dist.archives', 'hdfs:///python/dependency/xgb.zip#xgb')\
.getOrCreate()
def fun(x):
import sys
import os
sys.path.append(os.getcwd() + "/" + "xgb")
import xgboost
return xgboost.__version__
sc = spark.sparkContext
rdd = sc.parallelize([1,2,3,4,5,6,7], 3)
rdd.map(lambda x: fun(x)).distinct().collect()
執行Pyspark代碼驗證所有的Executor是否有加載到xgboost依賴包
1.存放在HDFS上的第三方依賴包可以存在多個,也可以將多個package包打包到一個zip包裏。
2.注意zip中的依賴包一定是通過pip命令成功安裝後的packages,而不是直接下在下來的安裝包。
3.在指定spark.yarn.dist.archives路徑時,必須指定在路徑最後加上#號和一個別名,該別名會在運行Executor和driver時作爲zip包解壓的目錄存在。
本文分享自微信公衆號 - Hadoop實操(gh_c4c535955d0f)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。