Spark3.2.1部署K8s报InvalidClassException类不兼容异常如何解决
问题说明
本地编译Spark v3.2.1版本部署至K8s集群时,spark-master节点观测到RPC消息处理异常,相关环境版本:
- JDK:openjdk8 (1.8)
- Scala:2.12.15
- Hadoop:3.3.1
核心报错日志:
2022-06-23 05:27:25.847 GMT ERROR [SPARK_MASTER] TransportRequestHandler: [rpc-server-4-1] Error while invoking RpcHandler#receive() for one-way message. java.io.InvalidClassException: org.apache.spark.deploy.ApplicationDescription; local class incompatible: stream classdesc serialVersionUID = 6543101073799644159, local class serialVersionUID = 1574364215946805297
异常核心:org.apache.spark.deploy.ApplicationDescription类序列化版本不兼容,RPC流中传输的该类serialVersionUID与Master节点本地加载的类serialVersionUID取值不匹配,触发Java序列化校验拦截。
根因定位方向
- 全链路Spark版本不统一:Spark提交客户端、Master节点部署包、K8s上Driver/Executor使用的Spark镜像,没有使用同一次编译产出的v3.2.1包。哪怕版本号同为3.2.1,只要编译时修改过源码、依赖版本有差异、编译参数不同,自动生成的serialVersionUID就会不同。
- 类路径冲突:Master节点classpath下残留了其他版本的spark-core jar,或者第三方依赖中重打包了不同版本的ApplicationDescription类,导致JVM加载了非预期版本的类。
- 编译环境不一致:分布式编译时各节点的Scala、Protobuf等编译依赖小版本不一致,产出的同版本号类生成的serialVersionUID存在差异。
解决操作
- 全量替换同批次编译产物
取本地一次完整编译产出的全套Spark包,统一替换Master节点部署包、spark-submit客户端包、K8s集群使用的Spark基础镜像。构建K8s Spark镜像时,必须直接使用本次编译输出的tgz包作为内置Spark发行版,禁止混用官方预编译包、历史编译包、其他来源的同版本号Spark包。 - 清理类路径冲突
登录Master节点执行命令排查重复的spark-core包:
删除所有非本次编译的spark-core包,移除Master启动参数中冗余的、包含Spark核心类的第三方依赖路径。# 查找SPARK_HOME下所有spark-core包 find $SPARK_HOME -name "spark-core_2.12-*.jar" # 提取Master进程启动类路径,排查是否引入外部路径下的旧版Spark类 ps -ef | grep org.apache.spark.deploy.master.Master | grep -v grep - 校验提交侧配置
执行spark-submit的节点必须使用和Master端完全一致的客户端包,不要通过SPARK_DIST_CLASSPATH等配置引入其他版本的Spark核心依赖。任务提交时如果指定了自定义Pod镜像,必须确认镜像内Spark版本与Master端完全对齐。 - 序列化版本一致性校验
编译完成后,对各端使用的spark-core包执行serialver命令,校验类版本号是否一致:
确保客户端、Master节点、K8s镜像内的该类serialVersionUID输出值完全相同。serialver -classpath ./spark-core_2.12-3.2.1.jar org.apache.spark.deploy.ApplicationDescription
内容的提问来源于stack exchange,提问作者Srivignesh
相关产品推荐
相关产品推荐

