hadoop No FileSystem for scheme:file
我试图运行一个简单的NaiveBayesClassifer
使用hadoop,得到这个错误
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对象正在打印 – Configuration: core-default.xml, core-site.xml
我认为它是因为jar子,有什么想法?
这是maven-assembly
插件破坏事件的典型案例。
为什么这发生在我们身上
不同的JAR( LocalFileSystem
hadoop-hdfs
, DistributedFileSystem
hadoop-hdfs
)在它们的META-INFO/services
目录中包含一个名为org.apache.hadoop.fs.FileSystem
的不同文件。 该文件列出了他们要声明的文件系统实现的规范类名(这称为通过java.util.ServiceLoader
实现的服务提供者接口,参见org.apache.hadoop.FileSystem
2622行 )。
当我们使用maven-assembly-plugin
,它把我们所有的JAR合并成一个,所有的META-INFO/services/org.apache.hadoop.fs.FileSystem
都会相互覆盖。 只剩下其中一个文件(最后一个被添加)。 在这种情况下,来自hadoop-commons
的FileSystem
列表将覆盖来自hadoop-hdfs
的列表,因此DistributedFileSystem
不再被声明。
我们如何解决它
在加载Hadoopconfiguration之后,在做任何与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() );
对于那些使用阴影插件的人,遵循david_p的build议,可以通过将ServicesResourceTransformer添加到插件configuration来合并阴影的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服务
为了logging,这仍然在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>
谢谢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>
花了我很多时间来解决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"
我希望这可以帮助!
我使用sbt程序集打包我的项目。 我也遇到这个问题。 我的解决scheme在这里。 第一步:在build.sbt中添加META-INF mergestrategy
case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard case PathList("META-INF", ps @ _*) => MergeStrategy.first
第二步:将hadoop-hdfs lib添加到build.sbt
"org.apache.hadoop" % "hadoop-hdfs" % "2.4.0"
第三步:清洁; sbt大会
希望以上信息可以帮助你。
假设你正在使用hadoop的mvn和cloudera分布。 我使用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>
对于maven,只需添加hadoop-hdfs的maven依赖项(请参阅下面的链接)将解决问题。
http://mvnrepository.com/artifact/org.apache.hadoop/hadoop-hdfs/2.7.1
我假设你使用maven构build示例。
请检查您尝试运行的JAR的内容。 特别是META-INFO/services
目录,文件org.apache.hadoop.fs.FileSystem
。 应该有filsystem实现类的列表。 检查行org.apache.hadoop.hdfs.DistributedFileSystem
存在于HDFS列表中, org.apache.hadoop.fs.LocalFileSystem
于本地文件系统中。
如果是这种情况,则必须在构build过程中重写引用的资源。
其他的可能性是你的类path中没有hadoop-hdfs.jar
,但这个概率很低。 通常如果你有正确的hadoop-client
依赖它不是一个选项。
另一个可能的原因(尽pipeOP问题本身并不受此影响)是如果您创build一个不加载默认值的configuration实例:
Configuration config = new Configuration(false);
如果你不加载默认值,那么你将不会得到FileSystem
实现的默认设置,当试图访问HDFS时会导致类似的错误。 切换到传入true
的无参构造函数来加载默认值可能会解决这个问题。
另外,如果您将自定义configuration位置(例如在文件系统上)添加到Configuration
对象,请注意您使用的addResource()
的哪个重载。 例如,如果您使用addResource(String)
则Hadoop假定该string是类path资源,如果您需要指定本地文件,请尝试以下操作:
File configFile = new File("example/config.xml"); config.addResource(new Path("file://" + configFile.getAbsolutePath()));
由于我的新手,我花了一些时间来弄清答案。 如果有人从一开始就需要帮助,这就是我想出来的:
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 }
如果你使用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 )
Configuration conf = new Configuration(); conf.set("fs.defaultFS", "hdfs://nameNode:9000"); FileSystem fs = FileSystem.get(conf);
设置fs.defaultFS为我工作! Hadoop的2.8.1
使用这个插件
<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>