如何从spark-shell加载S3文件中的RDD?

时间:2018-05-18 19:00:39

标签: scala apache-spark hadoop amazon-s3

我在S3中有一个文本文件,我希望将其加载到带有spark-shell的RDD中。

我已下载Spark 2.3.0 for Hadoop。天真的,我希望我只需要设置hadoop设置就可以了。

val inFile = "s3a://some/path"
val accessKey = "some-access-key"
val secretKey = "some-secret-key"

sc.hadoopConfiguration.set("fs.s3a.access.key", accessKey)
sc.hadoopConfiguration.set("fs.s3a.secret.key", secretKey)

sc.textFile(inFile).count()

println(run())

调用最后一行返回:

Failure(java.lang.RuntimeException: java.lang.ClassNotFoundException: Class org.apache.hadoop.fs.s3a.S3AFileSystem not found)

这似乎要求我提供包含S3AFileSystem的库。没问题 - 我下载了相应的jar并将此行添加到脚本的开头。

:require C:\{path-to-jar}\hadoop-aws-3.1.0.jar

现在,运行脚本在最后一行失败,出现各种类似的错误:

error: error while loading Partition, class file 'C:\spark\spark-2.3.0-bin-hadoop2.7\jars\spark-core_2.11-2.3.0.jar(org/apache/spark/Partition.class)' has location not matching its contents: contains class Partition

我此时已经迷失了 - 显然,以前定义run方法没有问题。

我可以直接自己访问Partition类,但是上面发生的一些事情阻止了代码访问分区。

scala> new org.apache.spark.Partition {def index = 3}
res6: org.apache.spark.Partition = $anon$1@3

奇怪的是,运行脚本的最后一行会在后续调用中产生不同的错误。

scala> sc.textFile(inFile).count()
java.lang.NoClassDefFoundError: org/apache/hadoop/fs/StreamCapabilities
  at java.lang.ClassLoader.defineClass1(Native Method)
  ...

documentation声称这是hadoop 3.1.0的一部分,我正在使用它,但在探索hadoop-aws-3.1.0.jar时,我看不到StreamCapabilities的痕迹。

我应该使用不同的罐子吗?我试图错误地解决这个问题吗?或者,我是否陷入了XY问题陷阱?

答案我试过

  • The official docs假设我在群集上运行脚本。但是我在本地运行spark-shell
  • This other StackOverflow question是针对较旧的问题。我使用s3a作为结果,但遇到了不同的问题。
  • 我也尝试过从2.6到3.1使用每一罐Hadoop,但没有用。

2 个答案:

答案 0 :(得分:1)

org.apache.hadoop.fs.StreamCapabilities位于hadoop-common-3.1.jar中 您可能正在混合使用Hadoop JAR的版本,因为s3a troubleshooting docs中的问题注定要失败。

Spark shell可以正常使用正确的JAR。但由于一些突出的问题,ASF Spark发布并不能与Hadoop 3.x一起使用。坚持使用Hadoop 2.8.x,你可以在没有太多痛苦的情况下获得良好的S3性能。

答案 1 :(得分:0)

我找到了解决问题的 路径,但我不知道为什么

  1. 创建SBT IntelliJ项目
  2. 包含以下依赖项和覆盖
  3. require

    运行脚本(无sbt console语句)
    scalaVersion := "2.11.12"
    
    libraryDependencies += "org.apache.spark" %% "spark-core" % "2.3.0"
    libraryDependencies += "org.apache.hadoop" % "hadoop-aws" % "3.1.0"
    libraryDependencies += "org.apache.hadoop" % "hadoop-client" % "3.1.0"
    
    dependencyOverrides += "com.fasterxml.jackson.core" % "jackson-core" % "2.8.7"
    dependencyOverrides += "com.fasterxml.jackson.core" % "jackson-databind" % "2.8.7"
    dependencyOverrides += "com.fasterxml.jackson.module" % "jackson-module-scala_2.11" % "2.8.7"
    
  4. 关键部分当然是重写杰克逊的依赖。