hadoop Kein Dateisystem für Schema: Datei


96

Ich versuche, eine einfache NaiveBayesClassiferVerwendung von Hadoop auszuführen, wobei dieser Fehler auftritt

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)

Code:

    Configuration configuration = new Configuration();
    NaiveBayesModel model = NaiveBayesModel.materialize(new Path(modelPath), configuration);// error in this line..

modelPathzeigt auf eine NaiveBayes.binDatei und das Konfigurationsobjekt wird gedruckt -Configuration: core-default.xml, core-site.xml

Ich denke, es liegt an Gläsern, irgendwelche Ideen?


Benötigen Sie weitere Informationen ...
Tariq

2
Ich kenne mich selbst nicht, aber ein kurzer Blick auf Google deutet darauf hin, dass es einige Probleme mit Gläsern gibt, auf die nicht wie von Ihnen vorgeschlagen verwiesen wird. Vielleicht geben die folgenden Links eine Antwort. groups.google.com/a/cloudera.org/forum/#!topic/scm-users/… grokbase.com/t/cloudera/cdh-user/134r64jm5t/…
Emile

Ich habe dem Klassenpfad hadoop-common-2.0.0-cdh4.3.0-sources.jar und hadoop-core-0.20.2.jar hinzugefügt. Ich habe es zuerst entfernt und es hat funktioniert, weiß nicht warum.
Mahender Singh

1
Hmm ... Könnten Sie mir bitte etwas über Ihre Umgebung erzählen? Bitte zeigen Sie mir auch die vollständige Ausnahmemeldung.
Tariq

Was ist der Wert von modelPath? Haben Sie versuchtfile:///path/to/dir
Chris White

Antworten:


174

Dies ist ein typischer Fall, in dem das maven-assemblyPlugin Dinge kaputt macht.

Warum ist uns das passiert?

Verschiedene JARs ( hadoop-commonsfür LocalFileSystem, hadoop-hdfsfür DistributedFileSystem) enthalten jeweils eine andere Datei, die org.apache.hadoop.fs.FileSystemin ihrem META-INFO/servicesVerzeichnis aufgerufen wird . Diese Datei listet die kanonischen Klassennamen der Dateisystemimplementierungen auf, die deklariert werden sollen (dies wird als Service Provider-Schnittstelle bezeichnet, die über implementiert wird java.util.ServiceLoader, siehe org.apache.hadoop.FileSystem#loadFileSystems).

Wenn wir verwenden maven-assembly-plugin, werden alle unsere JARs zu einem zusammengeführt und alle META-INFO/services/org.apache.hadoop.fs.FileSystemüberschreiben sich gegenseitig. Es bleibt nur eine dieser Dateien übrig (die letzte, die hinzugefügt wurde). In diesem Fall wird die FileSystemListe von hadoop-commonsvon Überschreibungen der Liste hadoop-hdfs, so DistributedFileSystemwurde nicht mehr erklärt.

Wie wir es behoben haben

Nach dem Laden der Hadoop-Konfiguration, aber kurz bevor Sie etwas in FileSystemBezug auf etwas tun , nennen wir dies:

    hadoopConfig.set("fs.hdfs.impl", 
        org.apache.hadoop.hdfs.DistributedFileSystem.class.getName()
    );
    hadoopConfig.set("fs.file.impl",
        org.apache.hadoop.fs.LocalFileSystem.class.getName()
    );

Update: das richtige Update

Ich wurde darauf aufmerksam gemacht, krookedkingdass es eine konfigurationsbasierte Möglichkeit gibt, die maven-assemblyVerwendung einer zusammengeführten Version aller FileSystemDienstdeklarationen zu machen. Lesen Sie seine Antwort unten.


13
Hier ist der entsprechende Code, der erforderlich ist, um dasselbe in Spark zu tun: 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)
Philip O.

8
Eigentlich habe ich gerade diese Maven-Abhängigkeit http://mvnrepository.com/artifact/org.apache.hadoop/hadoop-hdfs/2.2.0zu Maven hinzugefügt und das Problem gelöst.
B.Mr.W.

6
Ich habe versucht, hadoop-hdfs, hadoop-core, hadoop-common, hadoop-client hinzuzufügen. Außerdem habe ich versucht, hadoopConfig.set ("fs.hdfs.impl", org.apache.hadoop.hdfs.DistributedFileSystem.class.getName () hinzuzufügen. ); hadoopConfig.set ("fs.file.impl", org.apache.hadoop.fs.LocalFileSystem.class.getName ()); aber nicht funktioniert, wenn es von Eclipse ausgeführt wird, läuft es einwandfrei, aber wenn es mit dem Befehl java -cp ausgeführt wird, wird der obige Fehler angezeigt
Harish Pathak

1
Harish, was hast du gesehen? Gleiches Problem hier, aber mit Intellij
ThommyH

Nur eine Ergänzung zu der wunderbaren Antwort: Wenn man die Hadoop-JARS verwendet, aber den Job in einem Nicht-Hadoop-Cluster ausführt, wird "" hadoopConfig.set ("fs.hdfs.impl ....." "nicht In diesem Fall werden wir auf die Verwaltung des Assembly-Builds zurückgreifen. ZB in sbt könnten wir eine MergeStrategy von concat oder sogar filterDistinctLines durchführen
human

62

Wenn Sie das Schatten-Plugin verwenden, können Sie gemäß den Anweisungen von david_p die Dienste im schattierten Glas zusammenführen, indem Sie den ServicesResourceTransformer zur Plugin-Konfiguration hinzufügen:

  <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>

Dadurch werden alle org.apache.hadoop.fs.FileSystem-Dienste in einer Datei zusammengeführt


3
Diese Lösung gefällt mir am besten. Beheben Sie das Problem an der Quelle (dem Build), anstatt es nachträglich mit Konfigurationsänderungen zu patchen.
Kevin Pauli

1
Gute Antwort. Mein ähnlicher Fehler wurde behoben. Versucht mit Maven-Assembly-Plugin sowie Maven-Jar-Plugin / Maven-Abhängigkeit-Plugin-Kombination, aber nicht funktioniert. Diese Lösung hat meine Spark-App zum Laufen gebracht. Vielen Dank!
Somnathchakrabarti

Gute Antwort! Vielen Dank!
andrea.lagala

Dies sollte als akzeptierte Antwort markiert werden. Der ServicesResourceTransformer ist erforderlich, wenn JAR-Dateien mithilfe eines META-INF / services-Verzeichnisses Schnittstellen zu Implementierungen zuordnen. Weitere Informationen finden Sie hier: maven.apache.org/plugins/maven-shade-plugin/examples/…
Mario

Hervorragende Antwort.
Niranjan Subramanian

9

Für die Aufzeichnung geschieht dies immer noch in Hadoop 2.4.0. So frustrierend...

Ich konnte den Anweisungen in diesem Link folgen: http://grokbase.com/t/cloudera/scm-users/1288xszz7r/no-filesystem-for-scheme-hdfs

Ich habe meiner core-site.xml Folgendes hinzugefügt und es hat funktioniert:

<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>

8

danke 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);

oder

<property>
 <name>fs.hdfs.impl</name>
 <value>org.apache.hadoop.hdfs.DistributedFileSystem</value>
</property>

1
Erst nachdem ich dies gelesen hatte, wurde mir klar, dass das Conf hier die Hadoop-Konfiguration war: brucebcampbell.wordpress.com/2014/12/11/…
Sal

8

Ich habe ewig gebraucht, um es mit Spark 2.0.2 herauszufinden, aber hier ist mein Teil:

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)

Und die relevanten Teile meiner build.sbt:

scalaVersion := "2.11.8"
libraryDependencies += "org.apache.spark" %% "spark-core" % "2.0.2"

Ich hoffe das kann helfen!



5

Angenommen, Sie verwenden die mvn- und cloudera-Verteilung von hadoop. Ich verwende cdh4.6 und das Hinzufügen dieser Abhängigkeiten hat bei mir funktioniert. Ich denke, Sie sollten die Versionen der Hadoop- und MVN-Abhängigkeiten überprüfen.

<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>

Vergessen Sie nicht, das Cloudera MVN-Repository hinzuzufügen.

<repository>
        <id>cloudera</id>
        <url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
</repository>

4

Ich verwende sbt Assembly, um mein Projekt zu verpacken. Ich treffe auch dieses Problem. Meine Lösung ist hier. Schritt 1: Fügen Sie META-INF Mergestrategy in Ihre build.sbt ein

case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard
case PathList("META-INF", ps @ _*) => MergeStrategy.first

Schritt 2: Fügen Sie hadoop-hdfs lib zu build.sbt hinzu

"org.apache.hadoop" % "hadoop-hdfs" % "2.4.0"

Schritt 3: sbt sauber; sbt montage

Hoffe, die oben genannten Informationen können Ihnen helfen.


15
Eine bessere Lösung könnte darin bestehen, case PathList("META-INF", "services", "org.apache.hadoop.fs.FileSystem") => MergeStrategy.filterDistinctLines
Folgendes

Danke bei @ravwojdyla, ziemlich nette Lösung. Du hast meine Haare gerettet. Für die verlorenen Seelen, die diese Antwort für Apache Funken entdecken. Fügen Sie dies zu build.sbt hinzu, wenn die sbt-Assembly ordnungsgemäß funktioniert.
Greedy Coder

Die von @ravwojdyla bereitgestellte Lösung ist die einzige, die für mich funktioniert hat.
Sergey Kovalev

2
Die von @ravwojdyla gegebene Lösung ist ideal. Ich habe ein ähnliches Setup in build.sbt durchgeführt und Folgendes verwendet: `` `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} `` `
human

2

Ich gehe davon aus, dass Sie ein Beispiel mit Maven erstellen.

Bitte überprüfen Sie den Inhalt der JAR, die Sie ausführen möchten. Besonders META-INFO/servicesVerzeichnis, Datei org.apache.hadoop.fs.FileSystem. Es sollte eine Liste der Dateisystem-Implementierungsklassen vorhanden sein. Check Zeile org.apache.hadoop.hdfs.DistributedFileSystemist in der Liste für HDFS und org.apache.hadoop.fs.LocalFileSystemfür lokales Dateischema.

In diesem Fall müssen Sie die referenzierte Ressource während des Builds überschreiben.

Eine andere Möglichkeit ist, dass Sie einfach keinen hadoop-hdfs.jarin Ihrem Klassenpfad haben, aber dies hat eine geringe Wahrscheinlichkeit. Wenn Sie die richtige hadoop-clientAbhängigkeit haben, ist dies normalerweise keine Option.


HI Roman ..i hat das gleiche Problem und das META-INFO / services / org.apache.hadoop.fs.FileSystem hat keine hdfs-Zeile. Ich habe 2.0.0-mr1-cdh4.4.0 als einzige Abhängigkeit. Was muss ich tun? Irgendeine Dokumentation dazu? Mit Maven bauen
Sethi

2

Eine andere mögliche Ursache (obwohl die OP-Frage selbst nicht darunter leidet) ist, dass Sie eine Konfigurationsinstanz erstellen, die die Standardeinstellungen nicht lädt:

Configuration config = new Configuration(false);

Wenn Sie die Standardeinstellungen nicht laden, erhalten Sie nicht die Standardeinstellungen für Dinge wie die FileSystemImplementierungen, was zu identischen Fehlern wie diesen führt, wenn Sie versuchen, auf HDFS zuzugreifen. Das Umschalten auf den parameterlosen Konstruktor für die Übergabe truean Ladevorgaben kann dies beheben.

Wenn Sie dem ConfigurationObjekt benutzerdefinierte Konfigurationsspeicherorte hinzufügen (z. B. im Dateisystem), achten addResource()Sie außerdem darauf, welche Überlastung Sie verwenden. Wenn Sie beispielsweise verwenden, addResource(String)geht Hadoop davon aus, dass die Zeichenfolge eine Klassenpfadressource ist. Wenn Sie eine lokale Datei angeben müssen, versuchen Sie Folgendes:

File configFile = new File("example/config.xml");
config.addResource(new Path("file://" + configFile.getAbsolutePath()));

1

Aufgrund meiner Neulinge brauchte ich einige Zeit, um anhand der gegebenen Antworten eine Lösung zu finden. Das habe ich mir ausgedacht, wenn jemand von Anfang an Hilfe braucht:

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)

Ich benutze Spark 2.1

Und ich habe diesen Teil in meinem build.sbt

assemblyMergeStrategy in assembly := {
  case PathList("META-INF", xs @ _*) => MergeStrategy.discard
  case x => MergeStrategy.first
}

1
Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://nameNode:9000");
FileSystem fs = FileSystem.get(conf);

set fs.defaultFS funktioniert bei mir! Hadoop-2.8.1


1

Für SBT verwenden Sie unten mergeStrategy in build.sbt

mergeStrategy in assembly <<= (mergeStrategy in assembly) { (old) => {
    case PathList("META-INF", "services", "org.apache.hadoop.fs.FileSystem") => MergeStrategy.filterDistinctLines
    case s => old(s)
  }
}

0

Verwenden Sie dieses Plugin

<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>

0

Wenn Sie sbt verwenden :

//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
)

0

Ich hatte das gleiche Problem. Ich habe zwei Lösungen gefunden: (1) Manuelles Bearbeiten der JAR-Datei:

Öffnen Sie die JAR-Datei mit WinRar (oder ähnlichen Tools). Gehen Sie zu Meta-info> services und bearbeiten Sie "org.apache.hadoop.fs.FileSystem", indem Sie Folgendes anhängen:

org.apache.hadoop.fs.LocalFileSystem

(2) Ändern Sie die Reihenfolge meiner Abhängigkeiten wie folgt

<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>

0

Dies hat nichts mit Flink zu tun, aber ich habe dieses Problem auch in Flink gefunden.

Für Benutzer von Flink müssen Sie das vorgefertigte Hadoop herunterladen und darin ablegen /opt/flink/lib.


-1

Ich bin auch auf ein ähnliches Problem gestoßen. Core-site.xml und hdfs-site.xml als Ressourcen von conf (Objekt) hinzugefügt

Configuration conf = new Configuration(true);    
conf.addResource(new Path("<path to>/core-site.xml"));
conf.addResource(new Path("<path to>/hdfs-site.xml"));

Auch bearbeitete Versionskonflikte in pom.xml. (zB Wenn die konfigurierte Version von hadoop 2.8.1 ist, die Datei pom.xml jedoch die Version 2.7.1 hat, ändern Sie diese in 2.8.1.) Führen Sie die Maven-Installation erneut aus.

Dieser Fehler wurde für mich behoben.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.