it-swarm.com.de

hadoop Kein Dateisystem für Schema: Datei

Ich versuche eine einfache NaiveBayesClassifer mit hadoop auszuführen und bekomme diesen Fehler

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

modelPath zeigt auf NaiveBayes.bin-Datei und das Konfigurationsobjekt druckt - Configuration: core-default.xml, core-site.xml 

Ich denke es liegt an Krügen, irgendwelche Ideen?

76
Mahender Singh

Dies ist ein typischer Fall, wenn das maven-Assembly-Plugin die Dinge kaputt macht.

Warum ist uns das passiert?

Verschiedene JARs (hadoop-commons für LocalFileSystem, hadoop-hdfs für DistributedFileSystem) enthalten jeweils eine andere Datei mit dem Namen org.Apache.hadoop.fs.FileSystem in ihrem META-INFO/services-Verzeichnis. Diese Datei listet die kanonischen Klassennamen der Dateisystemimplementierungen auf, die sie deklarieren möchten (dies wird als Service Provider Interface bezeichnet, das über Java.util.ServiceLoader implementiert wird, siehe org.Apache.hadoop.FileSystemZeile 2622 ).

Wenn wir maven-Assembly-plugin verwenden, werden alle unsere JARs zu einer einzigen zusammengefügt, und alle META-INFO/services/org.Apache.hadoop.fs.FileSystem überschreiben sich gegenseitig. Es bleibt nur noch eine dieser Dateien (die zuletzt hinzugefügte). In diesem Fall überschreibt die Liste FileSystem aus hadoop-commons die Liste aus hadoop-hdfs, sodass DistributedFileSystem nicht mehr deklariert wurde.

Wie wir es repariert haben

Nach dem Laden der Hadoop-Konfiguration, aber kurz bevor Sie FileSystem-bezogen werden, rufen wir Folgendes auf:

    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 von +krookedking darauf aufmerksam gemacht, dass es eine konfigurationsbasierte Methode gibt, mit der maven-Assembly eine zusammengeführte Version aller FileSystem Services-Deklarationen verwenden kann . Fügen Sie der pom.xml-Datei das folgende Plugin hinzu:

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

Für diejenigen, die das Schatten-Plugin verwenden, können Sie die Dienste in der schattierten Dose nach den Empfehlungen von david_p 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

52
krookedking

Für das Protokoll ist dies immer noch in hadoop 2.4.0 der Fall. 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
Achaiah

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

Ich habe es ewig gewohnt, es mit Spark 2.0.2 herauszufinden, aber hier ist mein Beitrag:

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 meines build.sbt:

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

Ich hoffe das kann helfen!

7
Mauro Arnoldi

Fügen Sie für maven einfach die Maven-Abhängigkeit für hadoop-hdfs hinzu (siehe Link unten), um das Problem zu lösen.

http://mvnrepository.com/artifact/org.Apache.hadoop/hadoop-hdfs/2.7.1

5
kwky

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

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

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

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

Schritt 3: sbt sauber; sbt Versammlung

Hoffen Sie, dass die oben genannten Informationen Ihnen helfen können.

4
Haimei

Angenommen, Sie verwenden Mvn und Cloudera-Verteilung von Hadoop. Ich verwende cdh4.6 und fügte hinzu, dass diese Abhängigkeiten für mich funktionierten.

<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, Cloudera Mvn Repository hinzuzufügen.

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

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

Configuration config = new Configuration(false);

Wenn Sie die Standardwerte nicht laden, erhalten Sie nicht die Standardeinstellungen für Dinge wie die FileSystem-Implementierung, die beim Versuch, auf HDFS zuzugreifen, zu identischen Fehlern führen. Wenn Sie zum parameterlosen Konstruktor wechseln, um true zu übergeben, um die Standardwerte zu laden, kann dies möglicherweise behoben werden.

Wenn Sie dem Configuration-Objekt benutzerdefinierte Konfigurationsspeicherorte (z. B. im Dateisystem) hinzufügen, müssen Sie außerdem darauf achten, welche Überlastung von addResource() Sie verwenden. Wenn Sie beispielsweise addResource(String) verwenden, nimmt Hadoop an, 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()));
2
RobV

Ich nehme an, Sie bauen ein Muster mit Maven.

Bitte überprüfen Sie den Inhalt des JARs, den Sie ausführen möchten. Insbesondere META-INFO/services Verzeichnis, Datei org.Apache.hadoop.fs.FileSystem. Es sollte eine Liste von Dateisystem-Implementierungsklassen geben. Überprüfen Sie die Zeile org.Apache.hadoop.hdfs.DistributedFileSystem in der Liste für HDFS und org.Apache.hadoop.fs.LocalFileSystem für das lokale Dateischema.

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

Eine andere Möglichkeit ist, dass Sie einfach hadoop-hdfs.jar nicht in Ihrem Klassenpfad haben, aber dies hat eine geringe Wahrscheinlichkeit. Wenn Sie eine korrekte hadoop-client-Abhängigkeit haben, ist dies normalerweise keine Option.

2

Ich habe einige Zeit gebraucht, um aus den gegebenen Antworten herauszufinden, was auf meine Neugier zurückzuführen ist. Dies ist, was ich mir ausgedacht habe, wenn jemand anderes von Anfang an Hilfe benötigt:

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
Akavall
Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://nameNode:9000");
FileSystem fs = FileSystem.get(conf);

set fs.defaultFS funktioniert für mich! Hadoop-2.8.1

1
Asran Deng

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
Peluo

Verwenden Sie für SBT 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
Asad Raza