hadoop 没有用于方案的文件系统:文件
Posted
技术标签:
【中文标题】hadoop 没有用于方案的文件系统:文件【英文标题】:hadoop No FileSystem for scheme: file 【发布时间】:2013-06-20 08:11:58 【问题描述】:我正在尝试使用 hadoop 运行一个简单的NaiveBayesClassifer
,出现此错误
Exception in thread "main" java.io.IOException: No FileSystem for scheme: file
at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:1375)
at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:66)
at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:1390)
at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:196)
at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:95)
at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:180)
at org.apache.hadoop.fs.Path.getFileSystem(Path.java:175)
at org.apache.mahout.classifier.naivebayes.NaiveBayesModel.materialize(NaiveBayesModel.java:100)
代码:
Configuration configuration = new Configuration();
NaiveBayesModel model = NaiveBayesModel.materialize(new Path(modelPath), configuration);// error in this line..
modelPath
指向NaiveBayes.bin
文件,配置对象正在打印-Configuration: core-default.xml, core-site.xml
我认为是因为罐子,有什么想法吗?
【问题讨论】:
需要更多信息... 不认识自己,但在 google 上的快速浏览表明存在一些未按照您的建议引用的罐子的问题。也许以下链接会产生答案。 groups.google.com/a/cloudera.org/forum/#!topic/scm-users/…grokbase.com/t/cloudera/cdh-user/134r64jm5t/… 我正在将 hadoop-common-2.0.0-cdh4.3.0-sources.jar 和 hadoop-core-0.20.2.jar 添加到类路径中,我先删除了它,它工作不知道为什么。 嗯..你能告诉我你的环境吗?另外,请给我看完整的异常信息。 modelPath 的值是多少?你试过file:///path/to/dir
【参考方案1】:
如果您使用的是 Gradle Shadow 插件,那么这是您必须添加的配置:
shadowJar
mergeServiceFiles()
【讨论】:
为我工作,谢谢您的评论【参考方案2】:这个问题很老,但我最近遇到了同样的问题,错误的根源与这里的答案不同。
在我这边,根本原因是 hdfs 在路径开头遇到//
时试图解析权威:
$ hdfs dfs -ls //dev
ls: No FileSystem for scheme: null
因此,请尝试在代码的路径构建部分中查找双斜杠或空变量。
相关 Hadoop 票证:https://issues.apache.org/jira/browse/HADOOP-8087
【讨论】:
【参考方案3】:这是maven-assembly
插件破坏事物的典型案例。
为什么这会发生在我们身上
不同的 JAR(hadoop-commons
用于 LocalFileSystem
,hadoop-hdfs
用于 DistributedFileSystem
)每个都在其 META-INFO/services
目录中包含一个名为 org.apache.hadoop.fs.FileSystem
的不同文件。该文件列出了他们想要声明的文件系统实现的规范类名(这称为通过java.util.ServiceLoader
实现的服务提供者接口,参见org.apache.hadoop.FileSystem#loadFileSystems
)。
当我们使用maven-assembly-plugin
时,它会将我们所有的JAR 合并为一个,并且所有META-INFO/services/org.apache.hadoop.fs.FileSystem
会相互覆盖。这些文件中只剩下一个(最后一个添加的文件)。在这种情况下,hadoop-commons
中的 FileSystem
列表会覆盖 hadoop-hdfs
中的列表,因此不再声明 DistributedFileSystem
。
我们如何修复它
在加载 Hadoop 配置之后,但在做任何与FileSystem
相关的事情之前,我们称之为:
hadoopConfig.set("fs.hdfs.impl",
org.apache.hadoop.hdfs.DistributedFileSystem.class.getName()
);
hadoopConfig.set("fs.file.impl",
org.apache.hadoop.fs.LocalFileSystem.class.getName()
);
更新:正确修复
krookedking
引起我的注意,有一种基于配置的方法可以使maven-assembly
使用所有FileSystem
服务声明的合并版本,请查看下面的his answer。
【讨论】:
这是在 Spark 中执行相同操作所需的等效代码:val hadoopConfig: Configuration = spark.hadoopConfiguration hadoopConfig.set("fs.hdfs.impl", classOf[org.apache.hadoop.hdfs.DistributedFileSystem].getName) hadoopConfig.set("fs.file.impl", classOf[org.apache.hadoop.fs.LocalFileSystem].getName)
其实我只是将这个maven依赖http://mvnrepository.com/artifact/org.apache.hadoop/hadoop-hdfs/2.2.0
添加到maven中,问题就解决了。
我尝试添加 hadoop-hdfs、hadoop-core、hadoop-common、hadoop-client,Aslo 尝试添加 hadoopConfig.set("fs.hdfs.impl", org.apache.hadoop.hdfs .DistributedFileSystem.class.getName()); hadoopConfig.set("fs.file.impl", org.apache.hadoop.fs.LocalFileSystem.class.getName() );但不工作,从 eclipse 运行时运行正常,但从 java -cp 命令运行时显示上述错误
Harish,你看到了什么?这里有同样的问题,但是 intellij
只是对精彩答案的补充:如果有人使用 hadoop JARS 但在非 hadoop 集群中运行作业,则 """hadoopConfig.set("fs.hdfs.impl... .."""" 将不起作用。在这种情况下,我们将依靠管理程序集构建。例如,在 sbt 中,我们可以执行 concat 甚至 filterDistinctLines 的 mergeStrategy【参考方案4】:
这与 Flink 无关,但我在 Flink 中也发现了这个问题。
对于使用 Flink 的人,需要下载Pre-bundled Hadoop 并放入/opt/flink/lib
。
【讨论】:
【参考方案5】:我遇到了同样的问题。我找到了两个解决方案: (1) 手动编辑jar文件:
使用 WinRar(或类似工具)打开 jar 文件。转到 Meta-info > services ,并通过追加编辑“org.apache.hadoop.fs.FileSystem”:
org.apache.hadoop.fs.LocalFileSystem
(2) 改变我的依赖顺序如下
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-core</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>3.2.1</version>
</dependency>
</dependencies>
【讨论】:
【参考方案6】:对于 SBT,在 build.sbt 中的 mergeStrategy 下面使用
mergeStrategy in assembly <<= (mergeStrategy in assembly) (old) =>
case PathList("META-INF", "services", "org.apache.hadoop.fs.FileSystem") => MergeStrategy.filterDistinctLines
case s => old(s)
【讨论】:
【参考方案7】:我也遇到过类似的问题。 添加 core-site.xml 和 hdfs-site.xml 作为 conf (object) 的资源
Configuration conf = new Configuration(true);
conf.addResource(new Path("<path to>/core-site.xml"));
conf.addResource(new Path("<path to>/hdfs-site.xml"));
还在 pom.xml 中编辑了版本冲突。 (例如,如果配置的 hadoop 版本是 2.8.1,但在 pom.xml 文件中,依赖项的版本为 2.7.1,则将其更改为 2.8.1) 再次运行 Maven 安装。
这为我解决了错误。
【讨论】:
【参考方案8】:Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://nameNode:9000");
FileSystem fs = FileSystem.get(conf);
set fs.defaultFS 对我有用! Hadoop-2.8.1
【讨论】:
【参考方案9】:如果您使用的是 sbt:
//hadoop
lazy val HADOOP_VERSION = "2.8.0"
lazy val dependenceList = Seq(
//hadoop
//The order is important: "hadoop-hdfs" and then "hadoop-common"
"org.apache.hadoop" % "hadoop-hdfs" % HADOOP_VERSION
,"org.apache.hadoop" % "hadoop-common" % HADOOP_VERSION
)
【讨论】:
【参考方案10】:由于我是新手,我花了一些时间从给出的答案中找出解决办法。如果其他人从一开始就需要帮助,这就是我的想法:
import org.apache.spark.SparkContext
import org.apache.spark.SparkConf
object MyObject
def main(args: Array[String]): Unit =
val mySparkConf = new SparkConf().setAppName("SparkApp").setMaster("local[*]").set("spark.executor.memory","5g");
val sc = new SparkContext(mySparkConf)
val conf = sc.hadoopConfiguration
conf.set("fs.hdfs.impl", classOf[org.apache.hadoop.hdfs.DistributedFileSystem].getName)
conf.set("fs.file.impl", classOf[org.apache.hadoop.fs.LocalFileSystem].getName)
我使用的是 Spark 2.1
我的build.sbt
中有这部分
assemblyMergeStrategy in assembly :=
case PathList("META-INF", xs @ _*) => MergeStrategy.discard
case x => MergeStrategy.first
【讨论】:
【参考方案11】:我花了很长时间才用 Spark 2.0.2 弄明白,但这是我的一点:
val sparkBuilder = SparkSession.builder
.appName("app_name")
.master("local")
// Various Params
.getOrCreate()
val hadoopConfig: Configuration = sparkBuilder.sparkContext.hadoopConfiguration
hadoopConfig.set("fs.hdfs.impl", classOf[org.apache.hadoop.hdfs.DistributedFileSystem].getName)
hadoopConfig.set("fs.file.impl", classOf[org.apache.hadoop.fs.LocalFileSystem].getName)
还有我build.sbt
的相关部分:
scalaVersion := "2.11.8"
libraryDependencies += "org.apache.spark" %% "spark-core" % "2.0.2"
希望对你有帮助!
【讨论】:
【参考方案12】:另一个可能的原因(尽管 OPs 问题本身并没有受到此影响)是如果您创建了一个不加载默认值的配置实例:
Configuration config = new Configuration(false);
如果您不加载默认值,那么您将无法获得诸如 FileSystem
实现之类的默认设置,这会在尝试访问 HDFS 时导致类似的错误。切换到传入true
以加载默认值的无参数构造函数可能会解决此问题。
此外,如果您将自定义配置位置(例如在文件系统上)添加到 Configuration
对象,请注意您使用的 addResource()
的重载。例如,如果您使用addResource(String)
,则 Hadoop 假定该字符串是类路径资源,如果您需要指定本地文件,请尝试以下操作:
File configFile = new File("example/config.xml");
config.addResource(new Path("file://" + configFile.getAbsolutePath()));
【讨论】:
【参考方案13】:使用这个插件
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>allinone</shadedClassifierName>
<artifactSet>
<includes>
<include>*:*</include>
</includes>
</artifactSet>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>reference.conf</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer">
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
【讨论】:
【参考方案14】:对于 maven,只需添加 hadoop-hdfs 的 maven 依赖项(参考下面的链接)即可解决问题。
http://mvnrepository.com/artifact/org.apache.hadoop/hadoop-hdfs/2.7.1
【讨论】:
【参考方案15】:对于那些使用 shade 插件的人,按照 david_p 的建议,您可以通过将 ServicesResourceTransformer 添加到插件配置中来合并 shaded jar 中的服务:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
这会将所有 org.apache.hadoop.fs.FileSystem 服务合并到一个文件中
【讨论】:
我最喜欢这个解决方案。从源头(构建)修复问题,而不是事后通过配置更改修补它。 很好的答案。修复了我的类似错误。尝试使用 maven-assembly-plugin 以及 maven-jar-plugin/maven-dependency-plugin 组合,但没有奏效。这个解决方案使我的 Spark 应用程序正常工作。非常感谢! 很好的答案!非常感谢! 这应该被标记为接受的答案。当 jar 文件使用 META-INF/services 目录将接口映射到实现时,ServicesResourceTransformer 是必需的。更多信息可以在这里找到:maven.apache.org/plugins/maven-shade-plugin/examples/… 优秀的答案。【参考方案16】:感谢 david_p,scala
conf.set("fs.hdfs.impl", classOf[org.apache.hadoop.hdfs.DistributedFileSystem].getName);
conf.set("fs.file.impl", classOf[org.apache.hadoop.fs.LocalFileSystem].getName);
或
<property>
<name>fs.hdfs.impl</name>
<value>org.apache.hadoop.hdfs.DistributedFileSystem</value>
</property>
【讨论】:
读完后我才意识到这里的 conf 是 Hadoop 配置:brucebcampbell.wordpress.com/2014/12/11/…【参考方案17】:为了记录,这仍然发生在 hadoop 2.4.0 中。好郁闷……
我能够按照此链接中的说明进行操作:http://grokbase.com/t/cloudera/scm-users/1288xszz7r/no-filesystem-for-scheme-hdfs
我将以下内容添加到我的 core-site.xml 中并且它起作用了:
<property>
<name>fs.file.impl</name>
<value>org.apache.hadoop.fs.LocalFileSystem</value>
<description>The FileSystem for file: uris.</description>
</property>
<property>
<name>fs.hdfs.impl</name>
<value>org.apache.hadoop.hdfs.DistributedFileSystem</value>
<description>The FileSystem for hdfs: uris.</description>
</property>
【讨论】:
【参考方案18】:我使用 sbt 程序集来打包我的项目。我也遇到这个问题。我的解决方案在这里。 Step1:在你的 build.sbt 中添加 META-INF 合并策略
case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard
case PathList("META-INF", ps @ _*) => MergeStrategy.first
Step2:将 hadoop-hdfs lib 添加到 build.sbt
"org.apache.hadoop" % "hadoop-hdfs" % "2.4.0"
第三步:sbt clean; sbt 汇编
希望以上信息对您有所帮助。
【讨论】:
更好的解决方案可能是合并:case PathList("META-INF", "services", "org.apache.hadoop.fs.FileSystem") => MergeStrategy.filterDistinctLines
这将保留所有已注册的文件系统
感谢@ravwojdyla,非常简洁的解决方案。你救了我的头发。对于为 Apache spark 发现这个答案的迷失灵魂。当 sbt-assembly 正常工作时,将此添加到 build.sbt。
@ravwojdyla 提供的解决方案是唯一对我有用的解决方案。
@ravwojdyla 给出的解决方案是理想的。我在 build.sbt 中做了类似的设置并使用了: ``` assemblyMergeStrategy in assembly := case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard case PathList("META-INF", "services", "org.apache.hadoop.fs.FileSystem") => MergeStrategy.concat case _ => MergeStrategy.first ```【参考方案19】:
假设您正在使用 mvn 和 cloudera 分发的 hadoop。我正在使用 cdh4.6 并添加这些依赖项对我有用。我认为您应该检查 hadoop 和 mvn 依赖项的版本。
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
<version>2.0.0-mr1-cdh4.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.0.0-cdh4.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.0.0-cdh4.6.0</version>
</dependency>
不要忘记添加 cloudera mvn 存储库。
<repository>
<id>cloudera</id>
<url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
</repository>
【讨论】:
【参考方案20】:我假设您使用 maven 构建示例。
请检查您尝试运行的 JAR 的内容。尤其是META-INFO/services
目录,文件org.apache.hadoop.fs.FileSystem
。应该有 filsystem 实现类的列表。检查行 org.apache.hadoop.hdfs.DistributedFileSystem
是否存在于 HDFS 列表中,org.apache.hadoop.fs.LocalFileSystem
用于本地文件方案。
如果是这种情况,您必须在构建期间覆盖引用的资源。
另一种可能性是您的类路径中根本没有hadoop-hdfs.jar
,但这可能性很小。通常,如果您有正确的 hadoop-client
依赖项,则它不是一个选项。
【讨论】:
嗨 Roman ..我有同样的问题,META-INFO/services/org.apache.hadoop.fs.FileSystem 没有 hdfs 行。我有 2.0.0-mr1-cdh4。 4.0 作为唯一的依赖。我需要做什么?有关于此的任何文档?使用 Maven 构建以上是关于hadoop 没有用于方案的文件系统:文件的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Java 远程创建 Hadoop 文件系统的实例?