解決pyspark問題:在叢集中使用cluster模式,引入python複雜第三方庫
問題:在工作中,使用spark-summit部署python第三方庫儲存的xgboost模型(單機庫模型,非xgboost-4j),執行出錯,ImportError: No module name xxxx。使用第三方庫有:pandas、numpy、xgboost。因為沒有叢集許可權,模型安裝流程複雜,嘗試自己探索解決,看了國內外很多帖子,大致有3種情況:
- 單一檔案
- 自建模組 或python簡單第三方庫(不含.so檔案)
- python複雜第三方庫(含.so檔案,即動態載入庫,如numpy、pandas、xgboost)
1、單一檔案
(1)使用spark-submit命令中的--py-files選項並指定檔案的本地路徑,將依賴檔案提供給所有的執行程式。其中,dependency.py為依賴檔案,script.py為主程式檔案,均可以只放置在本地,提交任務後會上傳叢集。
spark/bin/spark-submit \
--master yarn \
--deploy-mode cluster \
--py-files dependency.py \
script.py
(2)在程式碼中使用sc.addPyFiles(path)函式,將所需檔案新增到SparkContext。
sc = SparkContext(master=”yarn-cluster”,appName=”myApp”)
sc.addPyFile(file_path)
2、自建模組或 python簡單第三方庫(不含.so檔案)
在指令碼中使用了自己構建的模組或者python的簡單第三方庫(不含.so檔案),如:
from model.file import *
則需要將模組打包成zip檔案,使用上述的--py-files或sc.addPyFiles(path)函式進行提交。提交後,即會將依賴庫分發到各節點。
注意:
(1)自己本地電腦python安裝的第三方庫,一般可在python shell中使用module.__file__ 檢視安裝位置
(2)打包時,需從模型根目錄進行打包,確保解壓後的檔案目錄即__init__.py等檔案。如模組資料夾位置為:.../site-packages/module,建議cd到該資料夾中,使用命令:
zip -r 目標目錄/deps.zip *
(3)當包檔案過大時,可以先提交叢集目錄後,在--py-files或sc.addPyFiles(path)中使用叢集目錄,以減少上傳時間,如:
spark/bin/spark-submit \
--master yarn \
--deploy-mode cluster \
--py-files hdfs://xxx/dependency.zip \
script.py
或
sc.addPyFile(hdfs://xxx/dependency.zip)
(4)當有多個模型需要引入時,可以使用逗號分隔或者多個sc.addPyFiles(path)
spark/bin/spark-submit \
--master yarn \
--deploy-mode cluster \
--py-files hdfs://xxx/dependency_1.zip,hdfs://xxx/dependency_2.zip \
script.py
或
sc.addPyFile(hdfs://xxx/dependency_1.zip)
sc.addPyFile(hdfs://xxx/dependency_2.zip)
3、python複雜第三方庫(含.so檔案,即動態載入庫,如numpy、pandas、xgboost)
如果模組依賴於已編譯的程式碼,如.so檔案(linux系統的,window系統相應會是.dll檔案),則很可能以上方法不起作用。主要原因是.so檔案需要動態編譯。
此時,可以建立一個虛擬環境,在虛擬環境中安裝python(建議直接安裝anaconda,可以直接解決大部分模組的安裝),然後將需要使用的複雜第三方庫安裝好。安裝庫有幾種可選方式:
- 有網路情況下:pip install module
- 無網路情況下:下載上傳輪子檔案module.whl,使用命令pip install module.whl。輪子檔案下載連結:https://pypi.org/
- 無網路情況下:tar.gz安裝等,自行搜尋
安裝好python及相應模型後,將整個虛擬環境打包,提交任務時指定python執行環境。虛擬環境的建立和使用請自行搜尋,如果本地python環境包含的庫不太多,直接打包本地python環境即可。
/spark/bin/spark-submit \
--conf spark.hadoop.hadoop.security.bdoc.access.id=xxx \
--conf spark.hadoop.hadoop.security.bdoc.access.key=xxx \
說明:以下4行主要解決轉pandas之類容易造成的資料傾斜,程式碼中注意將資料處理寫成運算元,結合mapPartition使用
--conf spark.default.parallelism=500 \
--conf spark.sql.auto.repartition=true \
--conf spark.sql.shuffle.partitions=2000 \
--conf spark.sql.sources.partitionColumnTypeInference.enabled=false \
說明:以下7行主要解決需要使用叢集未安裝第三方庫的問題,spark_env.zip為打包的python環境,包含python安裝後的bin、lib等檔案。即在本地python或python虛擬換機中安裝第三方庫後整體打包提交。#pyenv表示別名,用以下方指定執行換機
--archives hdfs://xxx/spark_env.zip#pyenv,hdfs://xxx/jdk1.8.0_161.tar.gz#jdk \
--conf spark.executorEnv.JAVA_HOME=jdk/jdk1.8.0_161 \
--conf spark.yarn.appMasterEnv.JAVA_HOME=jdk/jdk1.8.0_161 \
--conf spark.executorEnv.PYSPARK_PYTHON=pyenv/bin/python \
--conf spark.yarn.appMasterEnv.PYSPARK_PYTHON=pyenv/bin/python \
--conf spark.executorEnv.PYSPARK_DRIVER=pyenv/bin/python \
--conf spark.yarn.appMasterEnv.PYSPARK_DRIVER=pyenv/bin/python \
--master yarn \
--deploy-mode cluster \
--queue xx \
--driver-memory xG \
--executor-memory xG \
--num-executors x \
--executor-cores x \
說明:如程式碼中需使用hive讀取資料,可將叢集原hive配置檔案直接提交上去;如使用其他檔案,如已訓練的模型檔案可同步提交
--files spark/conf/hive-site.xml,xx \
xx.py
注意:此種情況下因需使用cluster模式,而客戶端無法看到詳細日誌,如報錯,需使用yarn命令檢視日誌。如想看其它使用者的日誌,可增加引數-appOwner 使用者名稱
/cmss/bch/bc1.3.4/hadoop/bin/yarn logs -applicationId application_xxxx
參考: