我有一个 Spark 应用程序,它从 S3 读取镶木地板文件。我的管道非常简单,并且在我的本地集群上运行良好。 这是我阅读镶木地板的相关部分:
final Dataset<Row> dataset = session
.read()
.option("mergeSchema", "true")
.option("recursiveFileLookup", true)
.parquet(s3Path);
但是,当我尝试在无服务器 EMR 上运行相同的 jar 时,出现上述错误。 我的无服务器 emr 版本是
emr-6.15.0
。
Spark 版本是 3.4.1
我已将这些罐子传递给我的会议
--conf spark.jars=s3://<bucker>/<prefix>/hadoop-aws-3.3.4.jar,s3://<bucker>/<prefix>/aws-java-sdk-bundle-1.12.569.jar,s3://<bucker>/<prefix>/aws-java-sdk-1.12.569.jar,s3://<bucker>/<prefix>/aws-crt-0.28.10.jar
知道是什么原因造成的吗?预先感谢您的帮助。
完整的堆栈跟踪:
Exception in thread "main" java.lang.NoClassDefFoundError: software/amazon/awssdk/transfer/s3/progress/TransferListener
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:467)
at org.apache.hadoop.conf.Configuration.getClassByNameOrNull(Configuration.java:2630)
at org.apache.hadoop.conf.Configuration.getClassByName(Configuration.java:2595)
at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:2691)
at org.apache.hadoop.fs.FileSystem.getFileSystemClass(FileSystem.java:3628)
at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:3663)
at org.apache.hadoop.fs.FileSystem.access$300(FileSystem.java:173)
at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:3767)
at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:3718)
at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:564)
at org.apache.hadoop.fs.Path.getFileSystem(Path.java:373)
at org.apache.spark.sql.execution.streaming.FileStreamSink$.hasMetadata(FileStreamSink.scala:53)
at org.apache.spark.sql.execution.datasources.DataSource.resolveRelation(DataSource.scala:366)
at org.apache.spark.sql.DataFrameReader.loadV1Source(DataFrameReader.scala:229)
at org.apache.spark.sql.DataFrameReader.$anonfun$load$2(DataFrameReader.scala:211)
at scala.Option.getOrElse(Option.scala:189)
at org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:211)
at org.apache.spark.sql.DataFrameReader.parquet(DataFrameReader.scala:563)
at org.apache.spark.sql.DataFrameReader.parquet(DataFrameReader.scala:548)
at com.apple.weather.MyJobMainClass.loadParquet(MyJobMainClass.java:53)
at com.apple.weather.MyJobMainClass.main(MyJobMainClass.java:91)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.apache.spark.deploy.JavaMainApplication.start(SparkApplication.scala:52)
at org.apache.spark.deploy.SparkSubmit.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:1066)
at org.apache.spark.deploy.SparkSubmit.doRunMain$1(SparkSubmit.scala:192)
at org.apache.spark.deploy.SparkSubmit.submit(SparkSubmit.scala:215)
at org.apache.spark.deploy.SparkSubmit.doSubmit(SparkSubmit.scala:91)
at org.apache.spark.deploy.SparkSubmit$$anon$2.doSubmit(SparkSubmit.scala:1158)
at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:1167)
at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
Caused by: java.lang.ClassNotFoundException: software.amazon.awssdk.transfer.s3.progress.TransferListener
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
我遇到的一个类似问题是 Hadoop 版本不匹配,在我的本地它工作正常,但我在 EMR 上运行时遇到了问题。
经过仔细分析,我发现在我们公司,我们使用的是私有存储库。 因此,在我的本地,我能够下载 hadoop、hadoop-aws 以及同一版本的所有其他相关依赖项。但在 EMR 上,由于它无法访问少数私有存储库,因此它从 Maven Central 中提取最新的依赖项。这导致少数 Hadoop 相关依赖项之间不匹配。
您可以做的是,在构建阶段,您可以打印依赖关系树,并验证所有相关依赖关系是否位于同一版本。
检查相同的命令。
mvn dependency:tree