108 votes

hadoop Pas de système de fichiers pour le schéma : file

J'essaie d'exécuter un simple NaiveBayesClassifer en utilisant hadoop, j'obtiens cette erreur

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 pointe vers NaiveBayes.bin et l'objet de configuration est imprimé - Configuration: core-default.xml, core-site.xml

Je pense que c'est à cause des pots, des idées ?

188voto

david_p Points 483

C'est un cas typique de la maven-assembly plugin qui casse des choses.

Pourquoi cela nous est arrivé

Différents JARs ( hadoop-commons para LocalFileSystem , hadoop-hdfs para DistributedFileSystem ) contiennent chacun un fichier différent appelé org.apache.hadoop.fs.FileSystem dans leur META-INFO/services répertoire. Ce fichier énumère les noms de classe canoniques des implémentations du système de fichiers qu'ils veulent déclarer (il s'agit d'une interface de fournisseur de services mise en œuvre par l'intermédiaire de java.util.ServiceLoader voir org.apache.hadoop.FileSystem#loadFileSystems ).

Lorsque nous utilisons maven-assembly-plugin il fusionne tous nos JARs en un seul, et tous les META-INFO/services/org.apache.hadoop.fs.FileSystem s'écrasent l'un l'autre. Il ne reste qu'un seul de ces fichiers (le dernier qui a été ajouté). Dans ce cas, le FileSystem liste de hadoop-commons écrase la liste de hadoop-hdfs donc DistributedFileSystem n'était plus déclarée.

Comment nous l'avons réparé

Après avoir chargé la configuration Hadoop, mais juste avant de faire quoi que ce soit FileSystem -liés, nous appelons cela :

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

Mise à jour : le correctif correct

Il a été porté à mon attention par krookedking qu'il existe un moyen, basé sur la configuration, de rendre la maven-assembly utiliser une version fusionnée de tous les FileSystem les déclarations de services, consultez sa réponse ci-dessous.

75voto

krookedking Points 913

Pour ceux qui utilisent le plugin shade, suivant le conseil de david_p, vous pouvez fusionner les services dans le jar shaded en ajoutant le ServicesResourceTransformer à la configuration du plugin :

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

Cela va fusionner tous les services org.apache.hadoop.fs.FileSystem dans un seul fichier.

9voto

Achaiah Points 81

Pour mémoire, cela se produit toujours dans hadoop 2.4.0. C'est tellement frustrant...

J'ai pu suivre les instructions de ce lien : http://grokbase.com/t/cloudera/scm-users/1288xszz7r/no-filesystem-for-scheme-hdfs

J'ai ajouté les éléments suivants à mon fichier core-site.xml et cela a fonctionné :

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

9voto

Mauro Arnoldi Points 91

J'ai mis du temps à comprendre avec Spark 2.0.2, mais voici ce que j'ai fait :

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)

Et les parties pertinentes de mon build.sbt :

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

J'espère que cela pourra vous aider !

8voto

Andy Points 191

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

ou

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X