如何以Yarn Client模式远程向EMR提交spark-submit任务并解决依赖报错
问题根因
第一个
ClassNotFoundException: com.amazon.ws.emr.hadoop.fs.EmrFileSystem错误根因:ECS上的原生Spark未包含EMR定制的emrfs文件系统相关依赖。
第二个InvalidClassException序列化冲突错误根因:即使大版本号都是2.4.7,EMR发行版的Spark会基于开源版本做定制补丁,和ECS上的原生Spark核心类实现有细微差异,直接把EMR的全部Spark jar放到HDFS通过spark.yarn.jars加载,会导致Driver端(运行在ECS)和Executor端(运行在YARN)的核心类序列化ID不匹配。
可行解决方案
优先选择改动最小的方案1即可解决问题:
方案1:仅补充缺失的emrfs依赖包
不需要修改原有Spark核心依赖,仅补充缺失的EmrFileSystem实现包即可:
- 从EMR主节点的
/usr/share/aws/emr/emrfs/lib/目录下获取emrfs-hadoop-ext.jar包,上传到ECS提交节点的本地路径,比如/opt/spark-custom-deps/ - 提交任务时添加以下参数,将该依赖包加载到Driver和Executor的类路径:
spark-submit \ --master yarn \ --deploy-mode client \ --jars /opt/spark-custom-deps/emrfs-hadoop-ext.jar \ --conf spark.driver.extraClassPath=emrfs-hadoop-ext.jar \ --conf spark.executor.extraClassPath=emrfs-hadoop-ext.jar \ --conf spark.hadoop.fs.s3.impl=com.amazon.ws.emr.hadoop.fs.EmrFileSystem \ --conf spark.hadoop.fs.s3a.impl=com.amazon.ws.emr.hadoop.fs.EmrFileSystem \ # 此处保留你原有任务的其他参数、主类、业务jar包、运行参数
方案2:ECS节点部署EMR官方客户端
如果后续还有其他EMR定制类缺失问题,直接统一客户端和集群的运行环境:
- 在ECS节点安装和目标EMR集群版本完全一致的EMR客户端包
- 同步集群的
core-site.xml、yarn-site.xml、spark-defaults.conf等配置文件到客户端对应目录 - 直接使用客户端自带的
spark-submit提交任务,所有依赖和集群完全匹配,不会出现类缺失或版本冲突问题。
写Redshift场景额外检查项
- 确保已经引入和Spark 2.4.7适配的
spark-redshift依赖包,推荐使用2.0.1版本 - 确保已经引入对应版本的Redshift JDBC驱动包
- 确保任务配置的Redshift临时S3路径有对应读写权限
内容的提问来源于stack exchange,提问作者jn5047
相关产品推荐
相关产品推荐

