我正在编写一个程序来将数据上传到某个s3a://链接。该计划是通过mvn install
编制的。在本地运行程序(如使用java -jar jarfile.jar
)没有返回任何错误。但是,当我使用spark-submit(如使用spark-submit jarfile.jar
)时,它返回了这样的错误:
线程“main”中的异常java.lang.NoSuchMethodError:org.apache.hadoop.conf.Configuration.reloadExistingConfigurations()V org.apache.hadoop.fs.s3a.S3AFileSystem.addDeprecatedKeys(S3AFileSystem.java:181)at org。 java.lang.Class.forName(java.Lava:。
错误日志跟踪到我的源代码的这部分:
sparkDataset
.write()
.format("parquet")
.mode(SaveMode.Overwrite)
.save("some s3a:// link");
其中sparkDataset
是org.apache.spark.sql.Dataset
的一个例子。
尝试How to access s3a:// files from Apache Spark?不成功,并返回另一个错误:
线程“main”中的异常java.lang.NoClassDefFoundError:org / apache / hadoop / fs / GlobalStorageStatistics $ StorageStatisticsProvider
来自java.lang.NoSuchMethodError: org.apache.hadoop.conf.Configuration.reloadExistingConfigurations()V的问题也不太可能,因为我可以在本地运行,其中兼容性不是问题。
另外,这些是我使用的相关库的版本:
AWS-Java的SDK-包:1.11.199 Hadoop的AWS:3.0.0我期待通过s3a://链接编写的文件。我认为依赖不是问题,因为我可以在本地运行。我在使用spark-submit运行这个程序时只遇到这个问题。任何人有任何想法如何解决这个问题?
编辑:此外,我已经检查过spark提交的spark版本据说是为hadoop 2.7及以上版本构建的。我严格使用hadoop 3.0.0。这可能是我的程序中发生此类错误的原因吗?
投票
来自Run spark-submit with my own build of hadoop的回答似乎指导我找到自己的解决方案。
根据我的理解,由于某些未知原因*,分发'spark-2.4.0-bin-hadoop2.7.tgz'提供的spark-submit将排除在您的应用程序中一起编译的所有hadoop包。
之所以引发NoSuchMethodError
错误,是因为在Hadoop版本2.8.x之前,方法reloadExistingConfiguration
不存在。看起来写一个镶木地板会以某种方式调用这种特殊的方法。
我的解决方案是使用'spark-2.4.0-without-hadoop.tgz'的单独发行版,同时将它连接到hadoop 3.0.0,这样即使spark-submit排除了你的软件包,它也将使用正确版本的hadoop执行期间的申请。
另外,由于无论如何都会通过spark-submit排除包,因此我不会在通过Maven编译时创建一个胖jar。相反,我会在执行期间使用标志--packages
来指定运行我的应用程序所需的依赖项。