pyspark使用anaconda后spark-submit方法(本人对其他文章进行的补充)

Pyspark集群任务与Anaconda环境配置
本文详述了在Pyspark集群环境中,如何通过使用自定义的Anaconda包解决Python库缺失或版本冲突的问题。通过具体实例,包括代码示例、Anaconda打包与上传至HDFS,以及spark-submit命令的详细参数设置,展示了如何确保任务运行时正确加载所需的Python环境。

在使用pyspark提交任务到集群时,经常会遇到服务器中python库不全或者版本不对的问题。此时可以使用参数–archives,从而使用自己的python包来解决。 
实验步骤如下:

测试代码使用jieba做分词,但服务器上面没有此库:

import jieba

jieba.initialize()
from pyspark.context import SparkContext
from pyspark.conf import SparkConf

sc = SparkContext(conf=SparkConf().setAppName("mnist_parallelize"))

s = sc.parallelize([1,2,3,4,5])
s.saveAsTextFile('hhc')


将anaconda打包:

zip -r anaconda2.zip anaconda2/



上传到hdfs:(如果是可视化的系统,是可以直接进行拖拽操作,其次,如果anaconda安装在hdfs内,可以不需要archives参数,直接给出PYSPARK_PYTHON的路径--anaconda的python路径即可,不需要压缩anaconda)

hadoop fs -put anaconda2.zip /user/xxx/tools


python上传后,在进行spark-submit时,会自动分发anaconda2的包到各个工作节点。但还需要给工作节点指定python解压路径:

spark-submit  \
--master yarn \
--deploy-mode cluster \
--num-executors 1 \
--executor-memory 1G \
--archives hdfs:///user/xxx/tools/anaconda2.zip#anaconda2 \
--conf spark.yarn.appMasterEnv.PYSPARK_PYTHON=./anaconda2/anaconda2/bin/python2 \
test.py


注:此时应特别注意解压路径,在anaconda2.zip在本地解压后,python的可执行路径为anaconda2/bin/python2,但在服务器上面会多一层。
--------------------- 


参考文章:https://blog.csdn.net/crookie/article/details/78351095 (90%内容来源于此)

本人添加了10%的内容
 

<think>我们正在解决一个Spark on YARN环境下,配置了`spark.driver.extraClassPath`和`spark.executor.extraClassPath`指向MySQL JDBC驱动,但驱动未生效的问题。根据用户提供的引用内容,我们注意到用户可能遇到了路径配置错误、环境变量问题或配置未正确加载的情况。 引用[1]中展示了一个配置示例,将MySQL驱动(版本5.1.40)的绝对路径配置到了`spark.executor.extraClassPath`和`spark.driver.extraClassPath`。引用[2]则说明在使用`--jars`参数时,如果位置放置不正确(比如放在最后)会导致驱动类找不到。 根据这些信息,我们可以从以下几个方面进行排查: 1. **路径是否正确**:检查配置的路径是否真实存在,并且文件可读。 2. **环境变量`SPARK_HOME`**:在配置文件中使用`$SPARK_HOME`可能不会被解析,建议使用绝对路径。 3. **配置文件是否生效**:检查`spark-defaults.conf`是否被正确加载,或者是否被其他配置覆盖。 4. **驱动版本兼容性**:检查使用的MySQL驱动版本是否与MySQL服务器版本兼容,以及是否与Spark版本兼容。 5. **配置位置**:在提交任务时,如果同时使用了`--jars`和配置文件中的`extraClassPath`,需要注意它们的关系,避免冲突。 下面我们详细说明每个排查步骤: ### 一、检查驱动文件路径 确保配置的绝对路径是正确的,并且所有节点(包括提交节点和YARN节点)上该路径都存在驱动文件。例如,在引用[1]中配置的路径是: ``` /usr/local/spark/jars/mysql-connector-java-5.1.40/mysql-connector-java-5.1.40-bin.jar ``` 需要登录到各个节点检查该路径是否存在,并且文件权限允许Spark进程(通常是yarn用户)读取。 ### 二、使用绝对路径,避免环境变量 在`spark-defaults.conf`中,不要使用环境变量(如`$SPARK_HOME`),因为Spark在读取配置文件时可能不会解析环境变量。应该使用完整的绝对路径。例如: ```properties spark.executor.extraClassPath /absolute/path/to/mysql-connector-java-5.1.40-bin.jar spark.driver.extraClassPath /absolute/path/to/mysql-connector-java-5.1.40-bin.jar ``` ### 三、验证配置文件是否被加载 可以通过在Spark提交命令中添加`--verbose`参数来查看加载的配置。例如: ```bash spark-submit --master yarn --deploy-mode client --verbose ... ``` 在输出中搜索`spark.executor.extraClassPath`和`spark.driver.extraClassPath`,确认配置的值是否正确。 ### 四、避免配置冲突 如果同时使用了`--jars`参数和配置文件中的`extraClassPath`,那么这两部分路径都会添加到类路径中。但是,如果`--jars`参数中包含了同一个驱动,可能会因为版本冲突导致问题。另外,引用[2]中提到,如果`--jars`参数的位置放错(比如在jar文件之后),则可能导致驱动加载失败。因此,建议在提交命令中,将`--jars`参数放在主jar之前。 正确的提交命令顺序: ```bash spark-submit \ --master yarn \ --deploy-mode client \ --jars /path/to/mysql-connector-java-8.0.26.jar \ --class your.main.class \ your-app.jar ``` ### 五、检查驱动版本兼容性 MySQL 5.x的驱动(如5.1.40)可能无法兼容MySQL 8.x服务器。同样,MySQL 8.x的驱动(如8.0.26)需要MySQL服务器5.7以上。请确保驱动版本与MySQL服务器版本匹配。 另外,MySQL 8.x驱动类名改为`com.mysql.cj.jdbc.Driver`,而MySQL 5.x驱动类名为`com.mysql.jdbc.Driver`。在代码中需要对应修改。 ### 六、类加载顺序问题 在Spark中,类加载可能有多种来源,包括: - Spark自身的类路径 - `--jars`指定的jar - `spark.{driver|executor}.extraClassPath`指定的路径 - 其他(如通过`spark.jars.packages`引入的包) 如果同一个类出现在多个位置,可能会使用第一个被加载的。因此,如果类路径中有多个不同版本的MySQL驱动,可能会导致问题。 ### 七、YARN集群的全局部署 生产环境推荐将驱动jar包部署到所有节点的相同路径下,并确保该路径在`extraClassPath`中配置。同时,确保所有节点上的路径和权限一致。 ### 八、测试驱动加载 可以通过一个简单的Spark任务来测试驱动是否被正确加载。例如,在Spark Shell中: ```bash spark-shell --master yarn --conf spark.executor.extraClassPath=/path/to/mysql-connector-java-8.0.26.jar --conf spark.driver.extraClassPath=/path/to/mysql-connector-java-8.0.26.jar ``` 然后在Scala中尝试加载驱动类: ```scala Class.forName("com.mysql.cj.jdbc.Driver") ``` 或者在PySpark中: ```python from pyspark.sql import SparkSession spark = SparkSession.builder.appName("MySQL test").getOrCreate() spark.sparkContext._jvm.Class.forName("com.mysql.cj.jdbc.Driver") ``` ### 九、查看YARN日志 如果任务失败,可以通过YARN命令查看日志: ```bash yarn logs -applicationId <application_id> ``` 在日志中搜索`ClassNotFoundException`或`No suitable driver`等关键词。 ### 十、考虑Hive元存储的驱动冲突 如果集群中同时部署了Hive,并且Hive的lib目录下有旧版本的MySQL驱动,可能会被优先加载。需要检查并移除冲突的驱动。 ### 总结解决方案步骤: 1. 确认驱动文件的绝对路径正确,并在所有节点存在。 2. 在`spark-defaults.conf`中使用绝对路径配置`extraClassPath`。 3. 避免在提交命令中同时使用`--jars`和`extraClassPath`指定同一个驱动,如果使用`--jars`,确保其位置正确(在主jar之前)。 4. 检查驱动版本与MySQL服务器版本兼容性,并确认代码中使用的驱动类名正确。 5. 通过简单的测试任务验证驱动加载。 6. 查看YARN日志,定位具体错误。 如果按照上述步骤仍然无法解决问题,可能需要进一步检查集群环境,例如Spark版本、YARN配置、节点环境等。 根据引用[2]中的经验,`--jars`参数的位置很重要,必须放在主jar之前。因此,如果用户同时使用了`--jars`参数,请务必注意位置。 最后,建议在生产环境中使用全局部署的方式(即将驱动jar包放入所有节点的`$SPARK_HOME/jars/`目录),这样即使不配置`extraClassPath`,Spark也会自动加载。但需要注意,如果使用这种方式,就不要在`extraClassPath`或`--jars`中再次指定同一个驱动,避免重复。 如果用户已经按照全局部署的方式(即将驱动放入`$SPARK_HOME/jars/`)但仍然失败,那么需要检查: - 是否所有节点(包括提交节点和所有NodeManager节点)都部署了驱动? - 是否重启了相关服务(如Spark History Server,如果用到的话)? - 是否有多版本驱动冲突? 希望以上排查步骤能帮助用户解决问题。 §§相关问题§§ 1. 如何检查Spark配置中`extraClassPath`是否生效? 2. 在YARN集群中,如何确保所有节点上的文件路径一致? 3. Spark提交任务时,`--jars`和`spark.jars`有什么区别? 4. 如何解决多个版本的JDBC驱动冲突? 5. 在Kerberos认证的集群中,如何配置Spark访问MySQL?</think>### Spark驱动配置未生效的排查与解决方案 根据您提供的配置信息和引用内容,以下是针对`spark.driver.extraClassPath`和`spark.executor.extraClassPath`配置MySQL驱动但未生效的完整排查流程: #### 一、核心问题诊断(按优先级排序) 1. **路径格式错误**(最常见问题) ```properties # 错误示例(使用环境变量) spark.executor.extraClassPath = $SPARK_HOME/jars/mysql-connector.jar # 正确示例(绝对路径) spark.executor.extraClassPath = /usr/local/spark/jars/mysql-connector-java-8.0.26.jar ``` - 🔍 验证方法:在所有YARN节点执行: ```bash ls /usr/local/spark/jars/mysql-connector-java-8.0.26.jar ``` 2. **配置加载顺序冲突**(引用[2]案例) - 提交命令中`--jars`位置错误导致覆盖: ```bash # 错误:--jars放在最后导致配置失效[^2] spark-submit ... --jars mysql-connector.jar # 正确:--jars必须放在主JAR前 spark-submit --jars mysql-connector.jar ... your-app.jar ``` 3. **驱动版本冲突** - 同时存在多个驱动版本(如Hive自带旧版驱动) - 🔍 检查命令: ```bash find $HIVE_HOME/lib -name "mysql-connector*.jar" find $SPARK_HOME/jars -name "mysql-connector*.jar" ``` 4. **权限问题**(YARN用户无法访问) ```bash # 检查文件权限 ls -l /usr/local/spark/jars/mysql-connector-java-8.0.26.jar # 修复权限(YARN默认使用nodemanager用户) sudo chmod 644 /usr/local/spark/jars/mysql-connector-java-8.0.26.jar sudo chown yarn:yarn /usr/local/spark/jars/mysql-connector-java-8.0.26.jar ``` #### 二、紧急解决方案 ```bash # 方案1:强制通过--jars加载(临时验证) spark-submit \ --master yarn \ --deploy-mode cluster \ --jars /absolute/path/to/mysql-connector-java-8.0.26.jar \ ...其他参数 # 方案2:物理部署到Spark jars目录(永久生效) # 在所有节点执行 sudo cp mysql-connector-java-8.0.26.jar $SPARK_HOME/jars/ ``` #### 三、配置验证流程 1. **检查实际加载的类路径** ```python # PySpark验证脚本 from pyspark.sql import SparkSession spark = SparkSession.builder.appName("ClassPathTest").getOrCreate() jvm = spark.sparkContext._jvm urls = jvm.org.apache.spark.util.Utils.getContextOrSparkClassLoader().getURLs() print("Driver ClassPath:") [print(url) for url in urls] ``` 2. **查看YARN容器日志** ```bash # 获取应用ID后检查日志 yarn logs -applicationId application_XXXXXX | grep -C 10 "mysql" ``` 3. **配置覆盖检查** ```bash # 检查是否有更高优先级配置 grep -r "extraClassPath" $SPARK_HOME/conf/ ``` #### 四、生产环境推荐配置 ```properties # $SPARK_HOME/conf/spark-defaults.conf spark.driver.extraClassPath /usr/local/spark/jars/mysql-connector-java-8.0.26.jar spark.executor.extraClassPath /usr/local/spark/jars/mysql-connector-java-8.0.26.jar # 添加服务发现文件(MySQL 8+必需) spark.jars.ivySettings /path/to/custom-ivy-settings.xml ``` #### 五、典型错误对照表 | 错误信息 | 解决方案 | |---------|---------| | `No suitable driver found` | 1. 检查绝对路径<br>2. 验证驱动文件是否存在<br>3. 检查文件权限[^1] | | `ClassNotFoundException` | 1. 确认驱动类名(com.mysql.cj.jdbc.Driver)<br>2. 检查--jars参数位置[^2] | | `Unsupported major.minor version` | 升级JDK版本(需JDK8+ for MySQL 8.x驱动) | | `Authentication plugin not supported` | 使用`mysql-connector-java-8.0.xx.jar`新版驱动 | > **关键发现**:在引用[2]的测试中,当`--jars`参数放置在主JAR文件之后时,Spark会忽略这些JAR导致`ClassNotFoundException`。这是Spark参数解析的特殊行为[^2]。 #### 六、持久化部署建议 ```bash # 使用Ansible批量部署驱动 - name: Deploy MySQL driver ansible.builtin.copy: src: mysql-connector-java-8.0.26.jar dest: /usr/local/spark/jars/ owner: yarn group: yarn mode: "0644" ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值