【问题标题】:Naive install of PySpark to also support S3 access天真的安装 PySpark 也支持 S3 访问
【发布时间】:2017-08-02 22:00:15
【问题描述】:

我想从 PySpark 读取存储在 S3 上的 Parquet 数据。

我从这里下载了 spark:

http://www.apache.org/dist/spark/spark-2.1.0/spark-2.1.0-bin-hadoop2.7.tgz

然后天真地将它安装到 Python 中

cd python
python setup.py install

这似乎运行良好,我可以导入 pyspark、制作 SparkContext 等。但是,当我阅读一些可公开访问的镶木地板数据时,我得到以下信息:

import pyspark
sc = pyspark.SparkContext('local[4]')
sql = pyspark.SQLContext(sc)
df = sql.read.parquet('s3://bucket-name/mydata.parquet')

我收到以下异常

Py4JJavaError: An error occurred while calling o55.parquet.
: java.io.IOException: No FileSystem for scheme: s3
    at org.apache.hadoop.fs.FileSystem.getFileSystemClass(FileSystem.java:2660)
    at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2667)
    at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:94)
    at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:2703)
    at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:2685)
    at 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.datasources.DataSource$$anonfun$14.apply(DataSource.scala:372)
    at org.apache.spark.sql.execution.datasources.DataSource$$anonfun$14.apply(DataSource.scala:370)
    at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:241)
    at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:241)
    at scala.collection.immutable.List.foreach(List.scala:381)
    at scala.collection.TraversableLike$class.flatMap(TraversableLike.scala:241)
    at scala.collection.immutable.List.flatMap(List.scala:344)
    at org.apache.spark.sql.execution.datasources.DataSource.resolveRelation(DataSource.scala:370)
    at org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:152)
    at org.apache.spark.sql.DataFrameReader.parquet(DataFrameReader.scala:441)
    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:280)
    at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132)
    at py4j.commands.CallCommand.execute(CallCommand.java:79)
    at py4j.GatewayConnection.run(GatewayConnection.java:214)
    at java.lang.Thread.run(Thread.java:745)

这个错误是从谷歌搜索中弹出的。到目前为止,所提供的解决方案都没有帮助。

我在一台个人电脑上使用 Linux (Ubuntu 16.04),没有安装太多其他东西(一切都很有货)。

更新

我已降级为 http://www.apache.org/dist/spark/spark-2.1.0/spark-2.1.0-bin-hadoop2.4.tgz 以默认包含 AWS。

现在很遗憾,我的 AWS 凭证没有被提取。我尝试了一些方法:

  1. 将它们作为 SparkConf 参数包括在内

    conf = (pyspark.SparkConf()
                   .set('fs.s3.awsAccessKeyId', ...')
                   .set('fs.s3.awsSecretAccessKey', '...'))
    sc = pyspark.SparkContext('local[4]', conf=conf)
    
  2. 将它们包含在我的本地 .aws/credentials 文件中
  3. 在 URL 中包含它们(不起作用,因为我的访问密钥有一个正斜杠)

不幸的是,在所有情况下,我都会收到如下回溯

IllegalArgumentException: 'AWS Access Key ID and Secret Access Key must be specified as the username or password (respectively) of a s3 URL, or by setting the fs.s3.awsAccessKeyId or fs.s3.awsSecretAccessKey properties (respectively).'

【问题讨论】:

  • 你试过s3ns3a前缀,对吗?
  • 我认为 hadoop-aws.jar 没有与 spark 捆绑。根据其他SO postSPARK-7481,捆绑aws 依赖项的问题仍在讨论中。你可以抢到最新的hadoop-aws jar
  • 在阅读了这些优秀的 cmets 后,用当前问题更新了原始问题

标签: python amazon-web-services apache-spark amazon-s3 pyspark


【解决方案1】:

使用预先构建的 spark 2.X 二进制文件的 Hadoop-2.4 构建(我相信它带有 s3 功能),您可以通过编程方式配置 spark 以通过以下方式提取 s3 数据:

import pyspark
conf = pyspark.SparkConf()

sc = pyspark.SparkContext('local[4]', conf=conf)
sc._jsc.hadoopConfiguration().set("fs.s3n.awsAccessKeyId", "")
sc._jsc.hadoopConfiguration().set("fs.s3n.awsSecretAccessKey", "")

sql = pyspark.SQLContext(sc)
df = sql.read.parquet('s3n://bucket-name/mydata.parquet')

需要注意的一个关键点是存储桶的 URI 和配置名称中的前缀 s3n

【讨论】:

  • 我收到了java.io.IOException: No FileSystem for scheme: s3n
  • @Gocht 连我都知道了。你修好了吗?
  • @TomJMuthirenthi 现在我在 Amazon EMR 上运行我的 pyspark 脚本,所以我与 S3 连接没有任何问题。
  • @Gocht :那你能帮我解决这个问题吗:stackoverflow.com/questions/49222171/…
  • 我在 Amazon EMR 上运行我的 pyspark 脚本,但我遇到了与 S3 连接的问题:/
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-10
  • 2021-12-23
  • 1970-01-01
  • 1970-01-01
  • 2021-05-11
  • 2016-02-08
  • 2012-06-07
相关资源
最近更新 更多