【问题标题】:Hadoop 2.9.2, Spark 2.4.0 access AWS s3a bucketHadoop 2.9.2、Spark 2.4.0 访问 AWS s3a 存储桶
【发布时间】:2019-05-24 03:57:04
【问题描述】:

已经有几天了,但我无法使用 Spark 从公共 Amazon Bucket 下载 :(

这里是spark-shell 命令:

spark-shell  --master yarn
              -v
              --jars file:/usr/local/hadoop/share/hadoop/tools/lib/hadoop-aws-2.9.2.jar,file:/usr/local/hadoop/share/hadoop/tools/lib/aws-java-sdk-bundle-1.11.199.jar
              --driver-class-path=/usr/local/hadoop/share/hadoop/tools/lib/hadoop-aws-2.9.2.jar:/usr/local/hadoop/share/hadoop/tools/lib/aws-java-sdk-bundle-1.11.199.jar

应用程序已启动,shell 等待提示:

   ____              __
  / __/__  ___ _____/ /__
 _\ \/ _ \/ _ `/ __/  '_/
/___/ .__/\_,_/_/ /_/\_\   version 2.4.0
   /_/

Using Scala version 2.11.12 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_191)
Type in expressions to have them evaluated.
Type :help for more information.

scala> val data1 = sc.textFile("s3a://my-bucket-name/README.md")

18/12/25 13:06:40 INFO MemoryStore: Block broadcast_0 stored as values in memory (estimated size 242.1 KB, free 246.7 MB)
18/12/25 13:06:40 INFO MemoryStore: Block broadcast_0_piece0 stored as bytes in memory (estimated size 24.2 KB, free 246.6 MB)
18/12/25 13:06:40 INFO BlockManagerInfo: Added broadcast_0_piece0 in memory on hadoop-edge01:3545 (size: 24.2 KB, free: 246.9 MB)
18/12/25 13:06:40 INFO SparkContext: Created broadcast 0 from textFile at <console>:24
data1: org.apache.spark.rdd.RDD[String] = s3a://my-bucket-name/README.md MapPartitionsRDD[1] at textFile at <console>:24

scala> data1.count()

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)
at org.apache.hadoop.conf.Configuration.getClassByName(Configuration.java:2099)
at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:2193)
at org.apache.hadoop.fs.FileSystem.getFileSystemClass(FileSystem.java:2654)
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.hadoop.mapreduce.security.TokenCache.obtainTokensForNamenodesInternal(TokenCache.java:97)
at org.apache.hadoop.mapreduce.security.TokenCache.obtainTokensForNamenodes(TokenCache.java:80)
at org.apache.hadoop.mapred.FileInputFormat.listStatus(FileInputFormat.java:206)
at org.apache.hadoop.mapred.FileInputFormat.getSplits(FileInputFormat.java:315)
at org.apache.spark.rdd.HadoopRDD.getPartitions(HadoopRDD.scala:204)
at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:253)
at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:251)
at scala.Option.getOrElse(Option.scala:121)
at org.apache.spark.rdd.RDD.partitions(RDD.scala:251)
at org.apache.spark.rdd.MapPartitionsRDD.getPartitions(MapPartitionsRDD.scala:49)
at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:253)
at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:251)
at scala.Option.getOrElse(Option.scala:121)
at org.apache.spark.rdd.RDD.partitions(RDD.scala:251)
at org.apache.spark.SparkContext.runJob(SparkContext.scala:2126)
at org.apache.spark.rdd.RDD.count(RDD.scala:1168)
... 49 elided
Caused by: java.lang.ClassNotFoundException: 
org.apache.hadoop.fs.StorageStatistics
  at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
  at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
  ... 77 more

scala>
  1. 所有 AWS 密钥、秘密密钥都在 hadoop/core-site.xml 中设置,如下所述:Hadoop-AWS module: Integration with Amazon Web Services
  2. 存储桶是公开的 - 任何人都可以下载(使用 curl -O 测试)
  3. 如您所见,所有 .jar 文件均由 Hadoop 本身从 /usr/local/hadoop/share/hadoop/tools/lib/ 文件夹提供
  4. spark-defaults.conf 中没有其他设置 - 只有在命令行中发送的设置
  5. 两个罐子都不提供这个类:

    jar tf /usr/local/hadoop/share/hadoop/tools/lib/hadoop-aws-2.9.2.jar | grep org/apache/hadoop/fs/StorageStatistics
    (no result)
    
    jar tf /usr/local/hadoop/share/hadoop/tools/lib/aws-java-sdk-bundle-1.11.199.jar | grep org/apache/hadoop/fs/StorageStatistics
    (no result)
    

我该怎么办?我忘了添加另一个罐子吗? hadoop-awsaws-java-sdk-bundle 的确切配置是什么?版本?

【问题讨论】:

标签: amazon-web-services apache-spark hadoop


【解决方案1】:

我使用 spark 2.4.5,这就是我所做的,它对我有用。我可以从本地的 Spark 连接到 AWS s3。

(1) Download spark 2.4.5 from here:https://archive.apache.org/dist/spark/spark-2.4.5/spark-2.4.5-bin-without-hadoop-scala-2.12.tgz. This spark does not have hadoop in it.
(2) Download hadoop. https://archive.apache.org/dist/hadoop/common/hadoop-3.2.1/hadoop-3.2.1.tar.gz
(3) Update .bash_profile
SPARK_HOME = <SPARK_PATH> #example /home/spark-2.4.5/spark-2.4.5-bin-without-hadoop-scala-2.12
PATH=$SPARK_HOME/bin
(4) Add Hadoop in spark env
Copy spark-env.sh.template as spark-env.sh
add export SPARK_DIST_CLASSPATH=$(<hadoop_path> classpath)
here <hadoop_path> is path to your hadoop /home/hadoop-3.2.1/bin/hadoop

【讨论】:

    【解决方案2】:

    我建议你不要做你做过的事。 您正在使用hadoop 2.9.2 上的hadoop 2.7.2 jar 运行预构建的 spark,并且您在类路径中添加了更多的 jar 以使用 hadoop 2.7.3 版本中的 s3 来解决问题。

    您应该做的是使用“无 hadoop”spark 版本 - 并通过配置提供 hadoop 文件,如以下链接所示 - https://spark.apache.org/docs/2.4.0/hadoop-provided.html

    主要部分:

    conf/spark-env.sh

    如果hadoop 二进制文件在您的路径中

    export SPARK_DIST_CLASSPATH=$(hadoop classpath)
    

    带有hadoop二进制的显式路径

    export SPARK_DIST_CLASSPATH=$(/path/to/hadoop/bin/hadoop classpath)
    

    传递 Hadoop 配置目录

    export SPARK_DIST_CLASSPATH=$(hadoop --config /path/to/configs classpath) 
    

    【讨论】:

      【解决方案3】:

      嗯……我终于找到了问题……

      主要问题是我为 Hadoop 预先安装了 Spark。它是“Hadoop 2.7 及更高版本的 v2.4.0 预构建”。正如您在上面看到的我的挣扎一样,这有点误导性的标题。实际上 Spark 附带了 不同 版本的 hadoop jars。来自 /usr/local/spark/jars/ 的清单表明它具有:

      hadoop-common-2.7.3.jar
      hadoop-client-2.7.3.jar
      ....

      它只缺少:hadoop-aws 和 aws-java-sdk。我在 Maven 存储库中进行了一点挖掘:hadoop-aws-v2.7.3 及其依赖项:aws-java-sdk-v1.7.4 和瞧!下载这些 jar 并将 它们 作为参数发送到 Spark。像这样:

      火花壳
      --master纱线
      -v
      --jars 文件:/home/aws-java-sdk-1.7.4.jar,文件:/home/hadoop-aws-2.7.3.jar
      --driver-class-path=/home/aws-java-sdk-1.7.4.jar:/home/hadoop-aws-2.7.3.jar

      干得好!!!

      我只是想知道为什么来自 Hadoop 的所有 jars(我将它们都作为参数发送到 --jars 和 --driver-class-path)没有赶上。 Spark 以某种方式自动选择它 jars 而不是我发送的内容

      【讨论】:

      • 挣扎了几天,直到找到这个答案。 hadoop的版本,spark是独立的还是内置hadoop的,hadoop-aws-的版本,aws-java-sdk-v的版本。这么多依赖。谢谢你,你救了我的一天。必须支持您的问题和答案。
      猜你喜欢
      • 1970-01-01
      • 2021-12-31
      • 2022-11-25
      • 2017-08-17
      • 2016-11-16
      • 2016-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多