Kesalahan Pyspark S3: java.lang.NoClassDefFoundError: com / amazonaws / services / s3 / model / MultiObjectDeleteException

Oct 27 2020

Tidak berhasil mengatur spark cluster yang dapat membaca file AWS s3. Software yang saya gunakan adalah sebagai berikut:

  1. hadoop-aws-3.2.0.jar
  2. aws-java-sdk-1.11.887.jar
  3. 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

1 stevel Oct 30 2020 at 15:02

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.

1 PrateekDubey Oct 31 2020 at 19:02

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)

banjoman Oct 27 2020 at 23:04

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.