Pyspark - Unable to read the data from AWS S3 bucket

Viewed 527

I am trying to read data from S3 bucket using Pyspark on Jupyterhub using the code below

config = pyspark.SparkConf().setAll([("spark.executor.instances", "4")\
,('spark.executor.memory', '50g')\
, ('spark.executor.cores', '4')\
, ('spark.cores.max', '48')\
, ('spark.driver.memory','50g')\
, ("spark.driver.maxResultSize", "35g")                             
, ("spark.jars", "/home/aws_jars/hadoop-aws-2.7.3.jar,/home/aws_jars/aws-java-sdk-1.11.30.jar")])

spark = SparkSession.builder.config(conf=config).getOrCreate()

# connect to AWS with boto3
sess = boto3.Session(region_name='us-east-1')
credentials = sess.get_credentials()
credentials = credentials.get_frozen_credentials()

sc=spark.sparkContext
hadoop_conf=sc._jsc.hadoopConfiguration()

hadoop_conf.set("fs.s3a.impl", "org.apache.hadoop.fs.s3a.S3AFileSystem")
hadoop_conf.set("fs.s3a.awsAccessKeyId", credentials.access_key)
hadoop_conf.set("fs.s3a.awsSecretAccessKey", credentials.secret_key)

df = spark.read.load('s3a://ml-bucket/spark-project/data/D2021117_BI_1982.txt',format ="csv",inferSchema="true")
df.show()

Here is the exception that I got.

Py4JJavaError: An error occurred while calling o63.load.
: java.lang.NoClassDefFoundError: com/amazonaws/AmazonServiceException

Here are the versions on the server

Hadoop 2.7.3
Python 3.6.12
Spark Version 3.1.2
openjdk version 1.8.0_312

I tried troubleshooting it with different hadoop-aws and aws-jdk versions. But, I am not able to make it work. I am also able to read it using Pandas but not with Pysaprk. Am I missing something here?

Update

Here is the complete error log after I replaced aws-java-sdk-1.11.30 with aws-java-sdk-bundle-1.11.901

Py4JJavaError: An error occurred while calling o59.load.
: java.lang.IllegalArgumentException
    at java.util.concurrent.ThreadPoolExecutor.<init>(ThreadPoolExecutor.java:1314)
    at java.util.concurrent.ThreadPoolExecutor.<init>(ThreadPoolExecutor.java:1237)
    at org.apache.hadoop.fs.s3a.S3AFileSystem.initialize(S3AFileSystem.java:280)
    at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:3303)
    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:377)
    at org.apache.spark.sql.DataFrameReader.loadV1Source(DataFrameReader.scala:325)
    at org.apache.spark.sql.DataFrameReader.$anonfun$load$3(DataFrameReader.scala:307)
    at scala.Option.getOrElse(Option.scala:189)
    at org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:307)
    at org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:239)
    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)
2 Answers

Try with aws-java-sdk-bundle. It has SDK all the classes for AWS services.

https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-bundle

Note: aws-java-sdk (https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk/1.12.126) actually doesn't have any java class (if you extract you will find out). It has all the was java SDK classes as dependencies so you need to compile to get all the dependencies. Alternatively, you can directly download the aws-java-sdk-bundle mentioned above and you are good to go.

Related