1. 背景
最近的项目使用yarn提交pyspark的任务,遇到了不少坑,目前已经成功地跑通了基于client和cluster两种模式的任务提交。特此记录一下。
2. 平台
大数据平台:某国产厂商的成熟大数据产品,基于容器的架构,四个节点,每个节点100-200G不等。
CPU:华为华为鲲鹏服务器,arm架构
OS:阿里云
程序:使用pyspark编程语言,程序位于节点1上。程序中用到了hjson配置文件,自定义的一些python包。
3. client模式与cluster模式区别
首先我们要知道spark程序主要有driver端和executor端。pyspark的程序主要是运行在多个executor里,但是如果程序中会使用df.toPandas()或者df.collect()并且进行一些基于python的操作,那么这些基于python的操作就会运行在driver里。
当使用client模式时,driver就位于我们程序所在的节点,也就是你运行代码的那个节点。
当使用cluster模式时,driver会由yarn根据资源占用情况,自动安排在某一个负载较少的节点上。
除此之外,使用client 模式提交的代码,可以在本地看到log,比如目前我在一个终端使用命令提交脚本,并输出日志:
./run_model.sh > log
而在另外一个终端中可以实时查看日志(过滤掉大量无用的INFO):
tail -f log -n 100 | grep -v 'INFO'
4. 用yarn模式提交任务
这部分是花时间最多的,因为涉及到pyspark_python和pyspark_driver_python的选择问题,也就是worker的python和driver的python需要使用一个版本。
最终成功的方式如下:
cluster模式:
export HADOOP_CONF_DIR=/etc/hdfs1/conf
export YARN_CONF_DIR=/etc/yarn1/conf
export SPARK_CONF_DIR=/mnt/disk1/TDH/spark-2.4.0-bin-hadoop2.7/conf
export HIVE_CONF_DIR=/etc/inceptor1/conf
export PYSPARK_DRIVER_PYTHON=py3/py3env_arm/bin/python3
export PYSPARK_PYTHON=py3/py3env_arm/bin/python3
export HADOOP_USER_NAME=hive
spark-2.4.0-bin-hadoop2.7/bin/spark-submit --master yarn --deploy-mode cluster --num-executors 20 --conf spark.yarn.dist.archives=hdfs:///tmp/py3env_arm.zip#py3 --driver-class-path /mnt/disk1/TDH/spark-2.4.0-bin-hadoop2.7/jars/mysql-connector-java-5.1.36.jar main.py
client模式:
export HADOOP_CONF_DIR=/etc/hdfs1/conf
export YARN_CONF_DIR=/etc/yarn1/conf
export SPARK_CONF_DIR=/mnt/disk1/TDH/spark-2.4.0-bin-hadoop2.7/conf
export HIVE_CONF_DIR=/etc/inceptor1/conf
export PYSPARK_DRIVER_PYTHON=/mnt/disk1/TDH/ai_audit/py3env_arm/bin/python3
export PYSPARK_PYTHON=py3/py3env_arm/bin/python3
export HADOOP_USER_NAME=hive
spark-2.4.0-bin-hadoop2.7/bin/spark-submit --master yarn --deploy-mode client --num-executors 20 --conf spark.yarn.dist.archives=./py3env_arm.zip#py3 --driver-class-path /mnt/disk1/TDH/spark-2.4.0-bin-hadoop2.7/jars/mysql-connector-java-5.1.36.jar main.py
有用的是通过export指定worke里的python path。
而所有在spark-submit里通过--conf spark.yarn.exectuorEnv指定的环境变量都是没用的。