我应该如何使用Spark在s3上加载文件?

时间:2018-05-24 02:08:01

标签: python apache-spark amazon-s3 pyspark

我通过pip install pyspark

安装了spark

我使用以下代码从s3上的文件创建数据框。

from pyspark.sql import SparkSession

spark = SparkSession.builder \
            .config('spark.driver.extraClassPath', '/home/ubuntu/spark/jars/aws-java-sdk-1.11.335.jar:/home/ubuntu/spark/jars/hadoop-aws-2.8.4.jar') \
            .appName("cluster").getOrCreate()
df = spark.read.load('s3a://bucket/path/to/file')

但是我收到了一个错误:

  

----------------------------------------------- ---------------------------- Py4JJavaError Traceback(最近的电话   最后)in()   ----> 1 df = spark.read.load(' s3a:// bucket / path / to / file')

     

〜/ miniconda3 / ENVS /观众/ LIB / python3.6 /站点包/ pyspark / SQL / readwriter.py   在加载(自我,路径,格式,架构,**选项)       164个self.options(**选项)       165 if isinstance(path,basestring):    - > 166返回self._df(self._jreader.load(path))       167 elif路径不是None:       168如果类型(路径)!= list:

     

〜/ miniconda3 / ENVS /观众/ LIB / python3.6 /站点包/ py4j / java_gateway.py   在调用(self,* args)1158回答=   self.gateway_client.send_command(command)1159 return_value   = get_return_value(    - > 1160回答,self.gateway_client,self.target_id,self.name)1161 1162 for temp_arg in temp_args:

     

〜/ miniconda3 / ENVS /观众/ LIB / python3.6 /站点包/ pyspark / SQL / utils.py   装饰(* a,** kw)        61 def deco(* a,** kw):        62尝试:   ---> 63返回f(* a,** kw)        64除了py4j.protocol.Py4JJavaError为e:        65 s = e.java_exception.toString()

     

〜/ miniconda3 / ENVS /观众/ LIB / python3.6 /站点包/ py4j / protocol.py   在get_return_value中(answer,gateway_client,target_id,name)       318提出Py4JJavaError(       319"调用{0} {1} {2}时发生错误。\ n"。    - > 320格式(target_id,"。",名称),值)       321其他:       322提出Py4JError(

     

Py4JJavaError:调用o220.load时发生错误。 :   java.lang.NoClassDefFoundError:org / apache / hadoop / fs / StorageStatistics     at java.lang.Class.forName0(Native Method)at   java.lang.Class.forName(Class.java:348)at   org.apache.hadoop.conf.Configuration.getClassByNameOrNull(Configuration.java:2134)     在   org.apache.hadoop.conf.Configuration.getClassByName(Configuration.java:2099)     在   org.apache.hadoop.conf.Configuration.getClass(Configuration.java:2193)     在   org.apache.hadoop.fs.FileSystem.getFileSystemClass(FileSystem.java:2654)     在   org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2667)     在org.apache.hadoop.fs.FileSystem.access $ 200(FileSystem.java:94)at   org.apache.hadoop.fs.FileSystem $ Cache.getInternal(FileSystem.java:2703)     在org.apache.hadoop.fs.FileSystem $ Cache.get(FileSystem.java:2685)     在org.apache.hadoop.fs.FileSystem.get(FileSystem.java:373)at   org.apache.hadoop.fs.Path.getFileSystem(Path.java:295)at   org.apache.spark.sql.execution.streaming.FileStreamSink $ .hasMetadata(FileStreamSink.scala:44)     在   org.apache.spark.sql.execution.datasources.DataSource.resolveRelation(DataSource.scala:354)     在   org.apache.spark.sql.DataFrameReader.loadV1Source(DataFrameReader.scala:239)     在   org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:227)     在   org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:174)     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at   sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)     在   sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)     在java.lang.reflect.Method.invoke(Method.java:498)at   py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:244)at at   py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:357)at   py4j.Gateway.invoke(Gateway.java:282)at   py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132)     在py4j.commands.CallCommand.execute(CallCommand.java:79)at   py4j.GatewayConnection.run(GatewayConnection.java:214)at   java.lang.Thread.run(Thread.java:748)引起:   抛出java.lang.ClassNotFoundException:   org.apache.hadoop.fs.StorageStatistics at   java.net.URLClassLoader.findClass(URLClassLoader.java:381)at   java.lang.ClassLoader.loadClass(ClassLoader.java:424)at   sun.misc.Launcher $ AppClassLoader.loadClass(Launcher.java:349)at at   java.lang.ClassLoader.loadClass(ClassLoader.java:357)... 28更多

如果我将s3a更改为s3s3n,则会要求提供aws访问密钥。但是,我已经在IAM中给出了ec2实例AmazonS3FullAccess

  

IllegalArgumentException:' AWS Access密钥ID和秘密访问密钥   必须通过设置fs.s3.awsAccessKeyId和来指定   fs.s3.awsSecretAccessKey属性(分别)。'

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:2)

您需要一种方法将AWS凭据公开给脚本。

使用botocore的下面示例可能会过度,但您无需滚动自己的AWS配置或凭据解析器。

首先,

  

pip install botocore

然后创建一个会话并盲目地解析您的凭据。凭据解析的顺序为documented here

 var colDef = {
            name: 'Dynamic Styles',
            field' 'dummyfield',
            cellStyle: function(params) {
                if (params.node.value=='Police') {
        //Here you can check the value and based on that you can change the color
                    //mark police cells as red
                    return {color: 'red', backgroundColor: 'green'};
                } else {
                    return null;
                }
            }
        }

修改

使用s3n文件系统客户端时,authentication properties就像这样

from pyspark.sql import SparkSession
import botocore.session

session = botocore.session.get_session()
credentials = session.get_credentials()

spark = (
    SparkSession
    .builder
    .config(
        'spark.driver.extraClassPath', 
        '/home/ubuntu/spark/jars/aws-java-sdk-1.11.335.jar:'
        '/home/ubuntu/spark/jars/hadoop-aws-2.8.4.jar')
    .config('fs.s3a.access.key', credentials.access_key)
    .config('fs.s3a.secret.key', credentials.secret_key)
    .appName("cluster")
    .getOrCreate()
)

df = spark.read.load('s3a://bucket/path/to/file')

答案 1 :(得分:1)

第一个错误告诉您Spark尝试加载类org.apache.hadoop.fs.StorageStatistics。你能确保你的Spark版本适合你的Hadoop JAR吗?通常,在此提交https://github.com/apache/hadoop/commit/687233f20d24c29041929dd0a99d963cec54b6df#diff-114b1833bd381e88382ade201dc692e8中添加了Spark尝试加载的类,并且关于3.0.0中首先发布的发布标记。由于您使用的是Hadoop 2.8.4,因此将其升级到3.0.0可能是一种解决方案。