web-dev-qa-db-ja.com

NoClassDefFoundError:org / Apache / hadoop / fs / StreamCapabilitiesでsparkでs3データを読み取り中

Amazon s3からデータを読み取る単純なspark=ローカルの開発マシン(Intellij経由)でジョブを実行したいと思います。

my build.sbtファイル:

scalaVersion := "2.11.12"

libraryDependencies ++= Seq(
  "org.Apache.spark" %% "spark-core" % "2.3.1",
  "org.Apache.spark" %% "spark-sql" % "2.3.1",
  "com.amazonaws" % "aws-Java-sdk" % "1.11.407",
  "org.Apache.hadoop" % "hadoop-aws" % "3.1.1"
)

私のコードスニペット:

val spark = SparkSession
    .builder
    .appName("test")
    .master("local[2]")
    .getOrCreate()

  spark
    .sparkContext
    .hadoopConfiguration
    .set("fs.s3n.impl","org.Apache.hadoop.fs.s3native.NativeS3FileSystem")

  val schema_p = ...

  val df = spark
    .read
    .schema(schema_p)
    .parquet("s3a:///...")

そして、私は次の例外を受け取ります:

Exception in thread "main" Java.lang.NoClassDefFoundError: org/Apache/hadoop/fs/StreamCapabilities
    at Java.lang.ClassLoader.defineClass1(Native Method)
    at Java.lang.ClassLoader.defineClass(ClassLoader.Java:763)
    at Java.security.SecureClassLoader.defineClass(SecureClassLoader.Java:142)
    at Java.net.URLClassLoader.defineClass(URLClassLoader.Java:467)
    at Java.net.URLClassLoader.access$100(URLClassLoader.Java:73)
    at Java.net.URLClassLoader$1.run(URLClassLoader.Java:368)
    at Java.net.URLClassLoader$1.run(URLClassLoader.Java:362)
    at Java.security.AccessController.doPrivileged(Native Method)
    at Java.net.URLClassLoader.findClass(URLClassLoader.Java:361)
    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)
    at Java.lang.Class.forName0(Native Method)
    at Java.lang.Class.forName(Class.Java:348)
    at org.Apache.hadoop.conf.Configuration.getClassByNameOrNull(Configuration.Java:2093)
    at org.Apache.hadoop.conf.Configuration.getClassByName(Configuration.Java:2058)
    at org.Apache.hadoop.conf.Configuration.getClass(Configuration.Java:2152)
    at org.Apache.hadoop.fs.FileSystem.getFileSystemClass(FileSystem.Java:2580)
    at org.Apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.Java:2593)
    at org.Apache.hadoop.fs.FileSystem.access$200(FileSystem.Java:91)
    at org.Apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.Java:2632)
    at org.Apache.hadoop.fs.FileSystem$Cache.get(FileSystem.Java:2614)
    at org.Apache.hadoop.fs.FileSystem.get(FileSystem.Java:370)
    at org.Apache.hadoop.fs.Path.getFileSystem(Path.Java:296)
    at org.Apache.spark.sql.execution.streaming.FileStreamSink$.hasMetadata(FileStreamSink.scala:45)
    at org.Apache.spark.sql.execution.datasources.DataSource.resolveRelation(DataSource.scala:354)
    at org.Apache.spark.sql.DataFrameReader.loadV1Source(DataFrameReader.scala:239)
    at org.Apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:227)
    at org.Apache.spark.sql.DataFrameReader.parquet(DataFrameReader.scala:622)
    at org.Apache.spark.sql.DataFrameReader.parquet(DataFrameReader.scala:606)
    at Test$.delayedEndpoint$Test$1(Test.scala:27)
    at Test$delayedInit$body.apply(Test.scala:4)
    at scala.Function0$class.apply$mcV$sp(Function0.scala:34)
    at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
    at scala.App$$anonfun$main$1.apply(App.scala:76)
    at scala.App$$anonfun$main$1.apply(App.scala:76)
    at scala.collection.immutable.List.foreach(List.scala:392)
    at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
    at scala.App$class.main(App.scala:76)
    at Test$.main(Test.scala:4)
    at Test.main(Test.scala)
Caused by: Java.lang.ClassNotFoundException: org.Apache.hadoop.fs.StreamCapabilities
    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 Java.lang.ClassLoader.loadClass(ClassLoader.Java:357)
    ... 41 more

s3a:///s3:///に置き換えると、別のエラーが発生します:No FileSystem for scheme: s3

私はAWSを初めて使用するので、s3:///s3a:///、またはs3n:///を使用する必要があるかどうかはわかりません。 AWS認証情報をaws-cliで設定済みです。

マシンにSpark=インストールはありません。

助けてくれてありがとう

9
ogen

私は S3Aトラブルシューティングドキュメント を見ることから始めます

どんな問題が発生しても、Hadoopバージョンがビルドされたものよりも新しいバージョンのAWS SDKを「ドロップイン」しようとしないでください。AWSSDKバージョンを変更しても問題は修正されず、表示されるスタックトレースのみが変更されます。

ローカルのsparkインストールにあるhadoop- JARのバージョンに関係なく、exactly同じバージョンが必要です。 hadoop-aws、およびhadoop-awsが組み込まれたaws SDKとまったく同じバージョン。詳細については mvnrepository を試してください。

15
Steve Loughran

私にとっては、上記の他にpom.xmlに次の依存関係を追加することで解決しました。

<dependency>
    <groupId>org.Apache.hadoop</groupId>
    <artifactId>hadoop-common</artifactId>
    <version>3.1.1</version>
</dependency>
4
Atihska