Spark Submit本地引入Elasticsearch-Hadoop Jar依赖失败求助
解决PySpark结构化流写入Elasticsearch的ClassNotFoundException问题
1. 为什么--py-files会失败
--py-files参数是Spark用来分发Python文件(.py、.zip、.egg)到集群节点的,完全不适合Java/Scala的JAR包。你用这个参数传elasticsearch-hadoop-7.7.1.jar,Spark根本不会把它加入JVM的类路径,自然找不到org.elasticsearch.spark.sql数据源类,这就是报错的直接原因。
2. 你可能选错了JAR包
这是最关键的问题:你使用的elasticsearch-hadoop-7.7.1.jar是Elasticsearch Hadoop的核心包,主要针对MapReduce/Hive场景,并不包含Spark SQL的数据源实现。针对Spark 2.x(你的版本是2.4.6),你需要下载专门的Spark绑定JAR:
- 对应Scala 2.11、Spark 2.x的JAR是:
elasticsearch-spark-20_2.11-7.7.1.jar - 这个JAR包含了
org.elasticsearch.spark.sql数据源类,是官方为Spark定制的包。
确认官方JAR的方式:
- 你可以从Maven中央仓库下载对应版本,或者Elasticsearch官方的Elasticsearch Hadoop页面获取,这些都是官方包。下载时务必匹配:
- Spark版本:Spark 2.x对应
spark-20前缀 - Scala版本:你的环境是Scala 2.11,所以JAR名要包含
_2.11 - Elasticsearch版本:尽量和你的ES集群版本一致(你用7.7.1没问题,只要ES集群是7.x系列即可)
- Spark版本:Spark 2.x对应
3. 使用--jars参数的正确姿势
拿到正确的JAR后,用--jars参数提交作业,注意以下几点:
本地模式/客户端模式
如果是本地测试或客户端模式(--deploy-mode client),确保JAR文件在提交机器的本地路径,或者所有集群节点都能访问的共享路径(比如NFS):
spark-submit --jars /path/to/elasticsearch-spark-20_2.11-7.7.1.jar /workspace/scripts/pyspark/FileStructuredStreaming_ES.py
YARN集群模式
如果是YARN集群模式(--deploy-mode cluster),需要把JAR上传到HDFS(因为Driver会在集群节点启动,本地路径无法访问):
# 先上传JAR到HDFS hdfs dfs -put elasticsearch-spark-20_2.11-7.7.1.jar /user/yourname/jars/ # 然后提交作业 spark-submit --deploy-mode cluster --jars hdfs:///user/yourname/jars/elasticsearch-spark-20_2.11-7.7.1.jar /workspace/scripts/pyspark/FileStructuredStreaming_ES.py
4. 额外的配置检查(如果还是失败)
如果用了正确的JAR和--jars参数仍报错,检查以下几点:
- 确认Spark配置中,
spark.driver.extraClassPath和spark.executor.extraClassPath有没有冲突的JAR,比如旧版本的Elasticsearch相关JAR,可能会导致类加载冲突; - 在代码中显式指定数据源类(虽然用
--packages时正常,但集群环境可能需要):df.writeStream \ .format("org.elasticsearch.spark.sql") \ .option("es.nodes", "your-es-host") \ .option("es.resource", "index/doc") \ .start() - 确保集群所有节点的Spark版本、Scala版本和你的本地环境一致(你的环境是Spark2.4.6、Scala2.11.0、Hadoop2.7,集群要匹配)。
内容的提问来源于stack exchange,提问作者Mohan Bagavathi




