尝试使用spark-shell读取位于S3的文件:
scala> val myRdd = sc.textFile("s3n://myBucket/myFile1.log")
lyrics: org.apache.spark.rdd.RDD[String] = s3n://myBucket/myFile1.log MappedRDD[55] at textFile at <console>:12
scala> myRdd.count
java.io.IOException: No FileSystem for scheme: s3n
at org.apache.hadoop.fs.FileSystem.getFileSystemClass(FileSystem.java:2607)
at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2614)
at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:91)
... etc ...
IOException:没有针对方案的文件系统:s3n 错误:
此错误的原因是什么?缺少依赖关系,缺少配置或误用sc.textFile()
?
或者可能是因为这个post似乎暗示了影响Hadoop 2.60特有的Spark构建的错误。我将尝试Spark for Hadoop 2.40,看看这是否解决了这个问题。
答案 0 :(得分:42)
确认这与针对Hadoop 2.60的Spark构建有关。刚刚安装了Spark 1.4.0 "Pre built for Hadoop 2.4 and later"(而不是Hadoop 2.6)。现在代码工作正常。
sc.textFile("s3n://bucketname/Filename")
现在引发了另一个错误:
java.lang.IllegalArgumentException: AWS Access Key ID and Secret Access Key must be specified as the username or password (respectively) of a s3n URL, or by setting the fs.s3n.awsAccessKeyId or fs.s3n.awsSecretAccessKey properties (respectively).
以下代码使用S3 URL格式显示Spark可以读取S3文件。使用开发机器(没有Hadoop库)。
scala> val lyrics = sc.textFile("s3n://MyAccessKeyID:MySecretKey@zpub01/SafeAndSound_Lyrics.txt")
lyrics: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[3] at textFile at <console>:21
scala> lyrics.count
res1: Long = 9
更好:如果AWS密钥具有转发“/”,则上述代码将在S3N URI中内联AWS凭证。在SparkContext中配置AWS凭证将修复它。无论S3文件是公共还是私有,代码都有效。
sc.hadoopConfiguration.set("fs.s3n.awsAccessKeyId", "BLABLA")
sc.hadoopConfiguration.set("fs.s3n.awsSecretAccessKey", "....") // can contain "/"
val myRDD = sc.textFile("s3n://myBucket/MyFilePattern")
myRDD.count
答案 1 :(得分:32)
尽管这个问题已经得到了接受,但我认为为什么会发生这种情况仍然缺失。所以我认为可能还有一个地方可以再提一个答案。
如果您添加了必需的hadoop-aws依赖项,那么您的代码应该有效。
启动Hadoop 2.6.0后,s3 FS连接器已移至名为hadoop-aws的独立库中。 还有一个Jira: Move s3-related FS connector code to hadoop-aws
这意味着针对Hadoop 2.6.0或更新版本构建的任何版本的spark都必须使用另一个外部依赖项才能连接到S3文件系统。
这是一个sbt示例,我已经尝试并使用针对Hadoop 2.6.0构建的Apache Spark 1.6.2按预期工作:
libraryDependencies + =“org.apache.hadoop”%“hadoop-aws”%“2.6.0”
在我的情况下,我遇到了一些依赖项问题,所以我通过添加排除来解决:
libraryDependencies + =“org.apache.hadoop”%“hadoop-aws”%“2.6.0”exclude(“tomcat”,“jasper-compiler”)excludeAll ExclusionRule(organization =“javax.servlet”)
在其他相关说明中,我还没有尝试过,但是建议使用“s3a”而不是“s3n”文件系统启动Hadoop 2.6.0。
第三代,s3a:文件系统。该文件系统绑定旨在成为替代s3n:的交换机,支持更大的文件并承诺更高的性能。
答案 2 :(得分:15)
您可以使用相应的jar添加--packages参数: 你提交的内容:
bin/spark-submit --packages com.amazonaws:aws-java-sdk-pom:1.10.34,org.apache.hadoop:hadoop-aws:2.6.0 code.py
答案 3 :(得分:8)
这是一个示例火花代码,可以读取s3上的文件
val hadoopConf = sparkContext.hadoopConfiguration
hadoopConf.set("fs.s3.impl", "org.apache.hadoop.fs.s3native.NativeS3FileSystem")
hadoopConf.set("fs.s3.awsAccessKeyId", s3Key)
hadoopConf.set("fs.s3.awsSecretAccessKey", s3Secret)
var jobInput = sparkContext.textFile("s3://" + s3_location)
答案 4 :(得分:6)
在Spark 2.0.2中遇到同样的问题。通过喂它罐子解决它。这就是我的目的:
$ spark-shell --jars aws-java-sdk-1.7.4.jar,hadoop-aws-2.7.3.jar,jackson-annotations-2.7.0.jar,jackson-core-2.7.0.jar,jackson-databind-2.7.0.jar,joda-time-2.9.6.jar
scala> val hadoopConf = sc.hadoopConfiguration
scala> hadoopConf.set("fs.s3.impl","org.apache.hadoop.fs.s3native.NativeS3FileSystem")
scala> hadoopConf.set("fs.s3.awsAccessKeyId",awsAccessKeyId)
scala> hadoopConf.set("fs.s3.awsSecretAccessKey", awsSecretAccessKey)
scala> val sqlContext = new org.apache.spark.sql.SQLContext(sc)
scala> sqlContext.read.parquet("s3://your-s3-bucket/")
显然,你需要在你从运行spark-shell的路径中放入jar
答案 5 :(得分:4)
我不得不将hadoop下载的jar文件复制到$SPARK_HOME/jars
目录中。使用--jars
标志或--packages
标志进行spark-submit不起作用。
详细说明:
(hadoop dir)/share/hadoop/tools/lib/
答案 6 :(得分:3)
有一个Spark JIRA,SPARK-7481,于今天,2016年10月20日开放,用于添加一个火花云模块,其中包含对所有s3a和azure isb:need以及测试的传递依赖性。
要匹配Spark PR。这就是我在我的spark构建中获得s3a支持的方式
如果您手动执行此操作,则必须获得hadoop-aws JAR与您的hadoop JARS的其余部分具有的确切版本,并且AWS JAR的版本100%与编译的Hadoop aws同步。对于Hadoop 2.7。{1,2,3,...}
hadoop-aws-2.7.x.jar
aws-java-sdk-1.7.4.jar
joda-time-2.9.3.jar
+ jackson-*-2.6.5.jar
将所有这些都粘贴到SPARK_HOME/jars
中。使用在Env vars或spark-default.conf
最简单的测试是你可以进行CSV文件的行计数
val landsatCSV = "s3a://landsat-pds/scene_list.gz"
val lines = sc.textFile(landsatCSV)
val lineCount = lines.count()
得到一个数字:一切都很好。获取堆栈跟踪。坏消息。
答案 7 :(得分:2)
对于Spark 1.4.x“为Hadoop 2.6及更高版本预构建”:
我刚从hadoop-aws-2.6.0.jar复制了所需的S3,S3native软件包 火花组装1.4.1-hadoop2.6.0.jar。
之后我重新启动了火花集群,它确实有效。 不要忘记检查装配罐的所有者和模式。
答案 8 :(得分:1)
S3N不是默认文件格式。您需要使用Hadoop版本构建您的Spark版本,该版本具有用于AWS兼容性的附加库。我在此处找到的其他信息https://www.hakkalabs.co/articles/making-your-local-hadoop-more-like-aws-elastic-mapreduce
答案 9 :(得分:1)
您可能必须使用s3a:/ scheme而不是s3:/或s3n:/ 但是,对于火花壳来说,它不是开箱即用(对我来说)。我看到以下stacktrace:
java.lang.RuntimeException: java.lang.ClassNotFoundException: Class org.apache.hadoop.fs.s3a.S3AFileSystem not found
at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:2074)
at org.apache.hadoop.fs.FileSystem.getFileSystemClass(FileSystem.java:2578)
at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2591)
at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:91)
at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:2630)
at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:2612)
at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:370)
at org.apache.hadoop.fs.Path.getFileSystem(Path.java:296)
at org.apache.hadoop.mapred.FileInputFormat.singleThreadedListStatus(FileInputFormat.java:256)
at org.apache.hadoop.mapred.FileInputFormat.listStatus(FileInputFormat.java:228)
at org.apache.hadoop.mapred.FileInputFormat.getSplits(FileInputFormat.java:313)
at org.apache.spark.rdd.HadoopRDD.getPartitions(HadoopRDD.scala:207)
at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:219)
at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:217)
at scala.Option.getOrElse(Option.scala:120)
at org.apache.spark.rdd.RDD.partitions(RDD.scala:217)
at org.apache.spark.rdd.MapPartitionsRDD.getPartitions(MapPartitionsRDD.scala:32)
at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:219)
at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:217)
at scala.Option.getOrElse(Option.scala:120)
at org.apache.spark.rdd.RDD.partitions(RDD.scala:217)
at org.apache.spark.SparkContext.runJob(SparkContext.scala:1781)
at org.apache.spark.rdd.RDD.count(RDD.scala:1099)
at $iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC.<init>(<console>:24)
at $iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC.<init>(<console>:29)
at $iwC$$iwC$$iwC$$iwC$$iwC$$iwC.<init>(<console>:31)
at $iwC$$iwC$$iwC$$iwC$$iwC.<init>(<console>:33)
at $iwC$$iwC$$iwC$$iwC.<init>(<console>:35)
at $iwC$$iwC$$iwC.<init>(<console>:37)
at $iwC$$iwC.<init>(<console>:39)
at $iwC.<init>(<console>:41)
at <init>(<console>:43)
at .<init>(<console>:47)
at .<clinit>(<console>)
at .<init>(<console>:7)
at .<clinit>(<console>)
at $print(<console>)
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:497)
at org.apache.spark.repl.SparkIMain$ReadEvalPrint.call(SparkIMain.scala:1065)
at org.apache.spark.repl.SparkIMain$Request.loadAndRun(SparkIMain.scala:1338)
at org.apache.spark.repl.SparkIMain.loadAndRunReq$1(SparkIMain.scala:840)
at org.apache.spark.repl.SparkIMain.interpret(SparkIMain.scala:871)
at org.apache.spark.repl.SparkIMain.interpret(SparkIMain.scala:819)
at org.apache.spark.repl.SparkILoop.reallyInterpret$1(SparkILoop.scala:857)
at org.apache.spark.repl.SparkILoop.interpretStartingWith(SparkILoop.scala:902)
at org.apache.spark.repl.SparkILoop.command(SparkILoop.scala:814)
at org.apache.spark.repl.SparkILoop.processLine$1(SparkILoop.scala:657)
at org.apache.spark.repl.SparkILoop.innerLoop$1(SparkILoop.scala:665)
at org.apache.spark.repl.SparkILoop.org$apache$spark$repl$SparkILoop$$loop(SparkILoop.scala:670)
at org.apache.spark.repl.SparkILoop$$anonfun$org$apache$spark$repl$SparkILoop$$process$1.apply$mcZ$sp(SparkILoop.scala:997)
at org.apache.spark.repl.SparkILoop$$anonfun$org$apache$spark$repl$SparkILoop$$process$1.apply(SparkILoop.scala:945)
at org.apache.spark.repl.SparkILoop$$anonfun$org$apache$spark$repl$SparkILoop$$process$1.apply(SparkILoop.scala:945)
at scala.tools.nsc.util.ScalaClassLoader$.savingContextLoader(ScalaClassLoader.scala:135)
at org.apache.spark.repl.SparkILoop.org$apache$spark$repl$SparkILoop$$process(SparkILoop.scala:945)
at org.apache.spark.repl.SparkILoop.process(SparkILoop.scala:1059)
at org.apache.spark.repl.Main$.main(Main.scala:31)
at org.apache.spark.repl.Main.main(Main.scala)
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:497)
at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:665)
at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:170)
at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:193)
at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:112)
at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
Caused by: java.lang.ClassNotFoundException: Class org.apache.hadoop.fs.s3a.S3AFileSystem not found
at org.apache.hadoop.conf.Configuration.getClassByName(Configuration.java:1980)
at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:2072)
... 68 more
我的想法 - 您必须手动手动添加hadoop-aws依赖项http://search.maven.org/#artifactdetails|org.apache.hadoop|hadoop-aws|2.7.1|jar但我不知道如何正确地将它添加到spark-shell。
答案 10 :(得分:1)
我遇到了同样的问题。在设置fs.s3n.impl的值并添加hadoop-aws依赖项后,它工作正常。
sc.hadoopConfiguration.set("fs.s3n.awsAccessKeyId", awsAccessKeyId)
sc.hadoopConfiguration.set("fs.s3n.awsSecretAccessKey", awsSecretAccessKey)
sc.hadoopConfiguration.set("fs.s3n.impl", "org.apache.hadoop.fs.s3native.NativeS3FileSystem")
答案 11 :(得分:0)
hadoop-aws
jar。$SPARK_HOME/jars
的位置。现在在您的Pyspark脚本中,设置AWS Access Key和Secret Access Key。
spark.sparkContext._jsc.hadoopConfiguration().set("fs.s3.awsAccessKeyId", "ACCESS_KEY")
spark.sparkContext._jsc.hadoopConfiguration().set("fs.s3.awsSecretAccessKey", "YOUR_SECRET_ACCESSS_KEY")
// where spark is SparkSession instance
对于Spark scala:
spark.sparkContext.hadoopConfiguration.set("fs.s3.awsAccessKeyId", "ACCESS_KEY")
spark.sparkContext.hadoopConfiguration.set("fs.s3.awsSecretAccessKey", "YOUR_SECRET_ACCESSS_KEY")
答案 12 :(得分:-1)
使用s3a而不是s3n。我在Hadoop工作上有类似的问题。从s3n切换到s3a后,它起作用了。
e.g。
S3A://myBucket/myFile1.log