java - 使用 spark-submit 部署我的程序时出现 java.lang.NoSuchMethodError
问题描述
我正在编写一个程序来将数据上传到某个 s3a:// 链接。该程序是通过编译的mvn install
。在本地运行程序(如 using java -jar jarfile.jar
)没有返回错误。但是,当我使用 spark-submit (如 using spark-submit jarfile.jar
)时,它返回了这样的错误:
org.apache.hadoop.fs.s3a.S3AFileSystem.addDeprecatedKeys(S3AFileSystem.java:181) 的 org.apache.hadoop.conf.Configuration.reloadExistingConfigurations()V 中的线程“主”java.lang.NoSuchMethodError 中的异常。 apache.hadoop.fs.s3a.S3AFileSystem.(S3AFileSystem.java:185) 在 java.lang.Class.forName0(Native Method) 在 java.lang.Class.forName(Class.java:348) ...
错误日志追溯到我的源代码的这一部分:
sparkDataset
.write()
.format("parquet")
.mode(SaveMode.Overwrite)
.save("some s3a:// link");
sparkDataset
的实例在哪里org.apache.spark.sql.Dataset
。
尝试如何从 Apache Spark 访问 s3a:// 文件?不成功并返回另一个错误,如下所示:
线程“主”java.lang.NoClassDefFoundError 中的异常:org/apache/hadoop/fs/GlobalStorageStatistics$StorageStatisticsProvider
java.lang.NoSuchMethodError: org.apache.hadoop.conf.Configuration.reloadExistingConfigurations()V的问题也不太可能,因为我可以在本地运行,其中兼容性不是问题。
此外,这些是我使用的相关库的版本:
- aws-java-sdk-bundle:1.11.199
- hadoop-aws:3.0.0
我期待通过 s3a:// 链接编写的文件。我认为依赖不是问题,因为我可以在本地运行。我只在使用 spark-submit 运行这个程序时遇到这个问题。有人对如何解决这个问题有任何想法吗?
编辑:此外,我已经检查了 spark 提交的 spark 版本据说是为 hadoop 2.7 及更高版本构建的。我严格使用hadoop 3.0.0。这可能是为什么我的程序中发生此类错误的线索吗?
解决方案
使用我自己构建的 hadoop 运行 spark-submit 的回答似乎指导我找到自己的解决方案。
根据我的理解,由于某些未知原因*,发行版“spark-2.4.0-bin-hadoop2.7.tgz”提供的 spark-submit 将排除在您的应用程序中一起编译的任何 hadoop 包。
NoSuchMethodError
引发错误的原因是该方法reloadExistingConfiguration
在 Hadoop 版本 2.8.x 之前不存在。似乎写一个镶木地板会以某种方式调用这个特定的方法。
我的解决方案是使用 'spark-2.4.0-without-hadoop.tgz' 的单独分发,同时将其连接到 hadoop 3.0.0,这样即使 spark-submit 排除了您的软件包中的包,它也会使用正确版本的 hadoop执行期间的应用程序。
此外,由于无论如何 spark-submit 会排除这些包,因此我不会在通过 Maven 编译期间创建胖 jar。相反,我会--packages
在执行期间使用该标志来指定运行我的应用程序所需的依赖项。