Kesalahan Pyspark S3: java.lang.NoClassDefFoundError: com / amazonaws / services / s3 / model / MultiObjectDeleteException
Tidak berhasil mengatur spark cluster yang dapat membaca file AWS s3. Software yang saya gunakan adalah sebagai berikut:
- hadoop-aws-3.2.0.jar
- aws-java-sdk-1.11.887.jar
- spark-3.0.1-bin-hadoop3.2.tgz
Menggunakan versi python: Python 3.8.6
from pyspark.sql import SparkSession, SQLContext
from pyspark.sql.types import *
from pyspark.sql.functions import *
import sys
spark = (SparkSession.builder
.appName("AuthorsAges")
.appName('SparkCassandraApp')
.getOrCreate())
spark._jsc.hadoopConfiguration().set("fs.s3a.access.key", "access-key")
spark._jsc.hadoopConfiguration().set("fs.s3a.secret.key", "secret-key")
spark._jsc.hadoopConfiguration().set("fs.s3a.impl","org.apache.hadoop.fs.s3a.S3AFileSystem")
spark._jsc.hadoopConfiguration().set("com.amazonaws.services.s3.enableV4", "true")
spark._jsc.hadoopConfiguration().set("fs.s3a.aws.credentials.provider","org.apache.hadoop.fs.s3a.BasicAWSCredentialsProvider")
spark._jsc.hadoopConfiguration().set("fs.s3a.endpoint", "")
input_file='s3a://spark-test-data/Fire_Department_Calls_for_Service.csv'
file_schema = StructType([StructField("Call_Number",StringType(),True),
StructField("Unit_ID",StringType(),True),
StructField("Incident_Number",StringType(),True),
...
...
# Read file into a Spark DataFrame
input_df = (spark.read.format("csv") \
.option("header", "true") \
.schema(file_schema) \
.load(input_file))
Kode gagal saat mulai mengeksekusi spark.read.format. Tampaknya kelas tersebut tidak dapat ditemukan. java.lang.NoClassDefFoundError: com.amazonaws.services.s3.model.MultiObjectDeleteException
File "<stdin>", line 1, in <module>
File "/usr/local/spark/spark-3.0.1-bin-hadoop3.2/python/pyspark/sql/readwriter.py", line 178, in load
return self._df(self._jreader.load(path))
File "/usr/local/spark/spark-3.0.1-bin-hadoop3.2/python/lib/py4j-0.10.9-src.zip/py4j/java_gateway.py", line 1304, in __call__
File "/usr/local/spark/spark-3.0.1-bin-hadoop3.2/python/pyspark/sql/utils.py", line 128, in deco
return f(*a, **kw)
File "/usr/local/spark/spark-3.0.1-bin-hadoop3.2/python/lib/py4j-0.10.9-src.zip/py4j/protocol.py", line 326, in get_return_value
py4j.protocol.Py4JJavaError: An error occurred while calling o51.load.
: java.lang.NoClassDefFoundError: com/amazonaws/services/s3/model/MultiObjectDeleteException
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at org.apache.hadoop.conf.Configuration.getClassByNameOrNull(Configuration.java:2532)
at org.apache.hadoop.conf.Configuration.getClassByName(Configuration.java:2497)
at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:2593)
at org.apache.hadoop.fs.FileSystem.getFileSystemClass(FileSystem.java:3269)
at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:3301)
at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:124) at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:3352)
at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:3320) at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:479) at org.apache.hadoop.fs.Path.getFileSystem(Path.java:361) at org.apache.spark.sql.execution.streaming.FileStreamSink$.hasMetadata(FileStreamSink.scala:46)
at org.apache.spark.sql.execution.datasources.DataSource.resolveRelation(DataSource.scala:366)
at org.apache.spark.sql.DataFrameReader.loadV1Source(DataFrameReader.scala:297)
at org.apache.spark.sql.DataFrameReader.$anonfun$load$2(DataFrameReader.scala:286) at scala.Option.getOrElse(Option.scala:189) at org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:286) at org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:232) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:244) at py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:357) at py4j.Gateway.invoke(Gateway.java:282) at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132) at py4j.commands.CallCommand.execute(CallCommand.java:79) at py4j.GatewayConnection.run(GatewayConnection.java:238) at java.lang.Thread.run(Thread.java:748) Caused by: java.lang.ClassNotFoundException: com.amazonaws.services.s3.model.MultiObjectDeleteException at java.net.URLClassLoader.findClass(URLClassLoader.java:382) at java.lang.ClassLoader.loadClass(ClassLoader.java:418) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
Saya sudah mencoba menemukan kombinasi yang tepat untuk toples dan python di atas tetapi saya tidak dapat menemukan campuran yang tepat. Saya mendapatkan semua jenis NoClassDefFoundError jadi saya memutuskan untuk menggunakan versi terbaru dari semua toples dan python yang saya cantumkan di atas tetapi masih tidak berhasil.
Saya ingin tahu versi toples dan python apa yang Anda gunakan untuk berhasil menyiapkan cluster yang dapat mengakses s3 menggunakan s3a melalui pyspark? Terima kasih sebelumnya atas tanggapan / bantuannya.
Jawaban
Hadoop 3.2 dibuat melawan 1.11.563; tempelkan sdk berbayang penuh dari versi spesifik tersebut di classpath Anda "aws-java-sdk-bundle" dan semuanya akan baik-baik saja.
SDK pernah "cerewet" di masa lalu ... dan peningkatan versi selalu menimbulkan kejutan. Bagi yang penasaran dengan pembaruan AWS SDK yang Memenuhi Syarat . Mungkin sudah waktunya seseorang melakukannya lagi.
Saya dapat menyelesaikan masalah ini di Spark 3.0 / Hadoop 3.2. Saya mendokumentasikan jawaban saya di sini juga - AWS EKS Spark 3.0, Kesalahan Hadoop 3.2 - NoClassDefFoundError: com / amazonaws / services / s3 / model / MultiObjectDeleteException
Gunakan bundel AWS Java SDK berikut dan masalah ini akan diselesaikan -
aws-java-sdk-bundle-1.11.874.jar (https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-bundle/1.11.874)
Jadi saya membersihkan semuanya dan menginstal ulang versi guci berikut dan berhasil: hadoop-aws-2.7.4.jar, aws-java-sdk-1.7.4.2.jar. Versi pemasangan Spark: spark-2.4.7-bin-hadoop2.7. Versi Python: Python 3.6.