hadoop No FileSystem pour le schéma: fichier

97

J'essaie d'exécuter un simple en NaiveBayesClassiferutilisant hadoop, obtenant 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..

modelPathpointe vers le NaiveBayes.binfichier et l'objet de configuration est en cours d'impression -Configuration: core-default.xml, core-site.xml

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

Mahender Singh
la source
Besoin de plus d'informations ...
Tariq
2
Je ne me connais pas, mais un rapide coup d'œil sur Google suggère qu'il y a des problèmes autour des pots qui ne sont pas référencés comme vous l'avez suggéré. Peut-être que les liens suivants donneront une réponse. groups.google.com/a/cloudera.org/forum/#!topic/scm-users/… grokbase.com/t/cloudera/cdh-user/134r64jm5t/…
Emile
J'ajoutais hadoop-common-2.0.0-cdh4.3.0-sources.jar et hadoop-core-0.20.2.jar au chemin de classe, j'ai supprimé en premier et cela a fonctionné je ne sais pas pourquoi.
Mahender Singh
1
Hmm..Pourriez-vous me parler de votre environnement? Veuillez également me montrer le message d'exception complet.
Tariq
Quelle est la valeur de modelPath? avez-vous essayéfile:///path/to/dir
Chris White

Réponses:

175

C'est un cas typique du maven-assemblyplugin qui casse des choses.

Pourquoi cela nous est arrivé

Différents JAR ( hadoop-commonspour LocalFileSystem, hadoop-hdfspour DistributedFileSystem) contiennent chacun un fichier différent appelé org.apache.hadoop.fs.FileSystemdans leur META-INFO/servicesrépertoire. Ce fichier répertorie les noms de classe canoniques des implémentations de système de fichiers qu'ils souhaitent déclarer (cela s'appelle une interface de fournisseur de services implémentée via java.util.ServiceLoader, voir org.apache.hadoop.FileSystem#loadFileSystems).

Lorsque nous l'utilisons maven-assembly-plugin, il fusionne tous nos JAR en un seul, et tous se META-INFO/services/org.apache.hadoop.fs.FileSystemremplacent les uns les autres. Un seul de ces fichiers reste (le dernier qui a été ajouté). Dans ce cas, la FileSystemliste de hadoop-commonsécrase la liste de hadoop-hdfs, donc DistributedFileSystemn'a plus été 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 FileSystemlié, nous appelons ceci:

    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 le fait krookedkingqu'il existe un moyen basé sur la configuration pour maven-assemblyutiliser une version fusionnée de toutes les FileSystemdéclarations de services, consultez sa réponse ci-dessous.

david_p
la source
13
Voici le code équivalent requis pour faire la même chose dans 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)
Philip O.
8
En fait, je viens d'ajouter cette dépendance http://mvnrepository.com/artifact/org.apache.hadoop/hadoop-hdfs/2.2.0maven à maven et le problème est résolu.
B.Mr.W.
6
J'ai essayé d'ajouter hadoop-hdfs, hadoop-core, hadoop-common, hadoop-client, Aslo a essayé d'ajouter hadoopConfig.set ("fs.hdfs.impl", org.apache.hadoop.hdfs.DistributedFileSystem.class.getName () ); hadoopConfig.set ("fs.file.impl", org.apache.hadoop.fs.LocalFileSystem.class.getName ()); mais ne fonctionne pas, lors de l'exécution depuis eclipse, il fonctionne bien, mais lors de l'exécution à partir de la commande java -cp, il affiche l'erreur ci-dessus
Harish Pathak
1
Harish, qu'avez-vous vu? Même problème ici mais avec intellij
ThommyH
Juste un ajout à la merveilleuse réponse: si l'on utilise les JARS hadoop mais que l'on exécute le travail dans un cluster non hadoop, "" "hadoopConfig.set (" fs.hdfs.impl ..... "" "" ne le sera pas Dans ce cas, nous retomberons sur la gestion de la construction de l'assembly. Par exemple, dans sbt, nous pourrions faire une mergeStrategy de concat ou même filterDistinctLines
human
62

Pour ceux qui utilisent le plugin shadow, en suivant les conseils de david_p, vous pouvez fusionner les services dans le jar ombré 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 fusionnera tous les services org.apache.hadoop.fs.FileSystem dans un seul fichier

krookedking
la source
3
J'aime mieux cette solution. Corrigez le problème à la source (la construction) plutôt que de le corriger avec des modifications de configuration après coup.
Kevin Pauli
1
Très bonne réponse. Correction de mon erreur similaire. J'ai essayé avec la combinaison maven-assembly-plugin ainsi que la combinaison maven-jar-plugin / maven-dependency-plugin mais n'a pas fonctionné. Cette solution a fait fonctionner mon application Spark. Merci beaucoup!
somnathchakrabarti
Très bonne réponse! Merci beaucoup!
andrea.lagala
Cela devrait être marqué comme la réponse acceptée. Le ServicesResourceTransformer est nécessaire lorsque les fichiers JAR mappent des interfaces avec des implémentations à l'aide d'un répertoire META-INF / services. Plus d'informations peuvent être trouvées ici: maven.apache.org/plugins/maven-shade-plugin/examples/…
Mario
Excellente réponse.
Niranjan Subramanian
9

Pour mémoire, cela se produit toujours dans hadoop 2.4.0. Si 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é ce qui suit à mon 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>
Achaiah
la source
8

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>
Andy
la source
1
Ce n'est qu'après avoir lu ceci que j'ai réalisé que la conf ici était la configuration Hadoop: brucebcampbell.wordpress.com/2014/12/11/…
Sal
8

Il m'a fallu des années pour le comprendre avec Spark 2.0.2, mais voici ma part:

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 peut vous aider!

Mauro Arnoldi
la source
5

En supposant que vous utilisez la distribution mvn et cloudera de hadoop. J'utilise cdh4.6 et l'ajout de ces dépendances a fonctionné pour moi. Je pense que vous devriez vérifier les versions des dépendances hadoop et 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>

n'oubliez pas d'ajouter le référentiel cloudera mvn.

<repository>
        <id>cloudera</id>
        <url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
</repository>
Husnu
la source
4

J'utilise l'assembly sbt pour empaqueter mon projet. Je rencontre également ce problème. Ma solution est ici. Étape 1: ajoutez la stratégie de fusion META-INF dans votre build.sbt

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

Étape 2: ajoutez la bibliothèque hadoop-hdfs à build.sbt

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

Étape 3: sbt propre; assemblage sbt

J'espère que les informations ci-dessus peuvent vous aider.

Haimei
la source
15
Une meilleure solution pourrait être de fusionner comme: case PathList("META-INF", "services", "org.apache.hadoop.fs.FileSystem") => MergeStrategy.filterDistinctLinesCela conservera tous les systèmes de fichiers enregistrés
ravwojdyla
Merci à @ravwojdyla, solution assez soignée. Vous avez sauvé mes cheveux. Pour les âmes perdues découvrant cette réponse pour Apache Spark. Ajoutez ceci à build.sbt lorsque sbt-assembly fonctionne correctement.
Greedy Coder
La solution fournie par @ravwojdyla est la seule qui a fonctionné pour moi.
Sergey Kovalev
2
La solution donnée par @ravwojdyla est idéale. J'ai fait une configuration similaire dans build.sbt et utilisé: `` `` 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} `` `
humain
2

Je suppose que vous créez un échantillon avec maven.

Veuillez vérifier le contenu du JAR que vous essayez d'exécuter. Surtout META-INFO/servicesrépertoire, fichier org.apache.hadoop.fs.FileSystem. Il devrait y avoir une liste de classes d'implémentation de filsystem. La ligne de contrôle org.apache.hadoop.hdfs.DistributedFileSystemest présente dans la liste pour HDFS etorg.apache.hadoop.fs.LocalFileSystem pour le schéma de fichier local.

Si tel est le cas, vous devez remplacer la ressource référencée lors de la génération.

Une autre possibilité est que vous n'avez tout simplement pas hadoop-hdfs.jardans votre chemin de classe, mais cela a une faible probabilité. Habituellement, si vous avez une hadoop-clientdépendance correcte, ce n'est pas une option.

Roman Nikitchenko
la source
HI Roman .. j'ai le même problème et META-INFO / services / org.apache.hadoop.fs.FileSystem n'a pas de ligne hdfs. J'ai 2.0.0-mr1-cdh4.4.0 comme seule dépendance. Qu'est-ce que je dois faire? Une documentation à ce sujet? Utilisation de Maven pour construire
sethi
2

Une autre cause possible (bien que la question OPs n'en souffre pas elle-même) est si vous créez une instance de configuration qui ne charge pas les valeurs par défaut:

Configuration config = new Configuration(false);

Si vous ne chargez pas les valeurs par défaut, vous n'obtiendrez pas les paramètres par défaut pour des choses comme les FileSystemimplémentations, ce qui conduit à des erreurs identiques comme celle-ci lorsque vous essayez d'accéder à HDFS. Le passage au constructeur sans paramètre de transmission trueaux valeurs par défaut de chargement peut résoudre ce problème.

De plus, si vous ajoutez des emplacements de configuration personnalisés (par exemple sur le système de fichiers) au Configuration objet, addResource()faites attention à la surcharge que vous utilisez. Par exemple, si vous utilisez, addResource(String)Hadoop suppose que la chaîne est une ressource de chemin de classe, si vous devez spécifier un fichier local, essayez ce qui suit:

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

Il m'a fallu un certain temps pour trouver une solution à partir des réponses données, en raison de ma nouveauté. Voici ce que j'ai proposé, si quelqu'un d'autre a besoin d'aide dès le début:

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)

J'utilise Spark 2.1

Et j'ai cette part dans mon build.sbt

assemblyMergeStrategy in assembly := {
  case PathList("META-INF", xs @ _*) => MergeStrategy.discard
  case x => MergeStrategy.first
}
Akavall
la source
1
Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://nameNode:9000");
FileSystem fs = FileSystem.get(conf);

set fs.defaultFS fonctionne pour moi! Hadoop-2.8.1

Asran Deng
la source
1

Pour SBT, utilisez ci-dessous mergeStrategy dans 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)
  }
}
Asad Raza
la source
0

Utilisez ce 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>
Harish Pathak
la source
0

Si vous utilisez 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
)
Peluo
la source
0

J'ai fait face au même problème. J'ai trouvé deux solutions: (1) Édition manuelle du fichier jar:

Ouvrez le fichier jar avec WinRar (ou des outils similaires). Allez dans Meta-info> services, et éditez "org.apache.hadoop.fs.FileSystem" en ajoutant:

org.apache.hadoop.fs.LocalFileSystem

(2) Changer l'ordre de mes dépendances comme suit

<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>
Mohammad-Ali
la source
0

Ce n'est pas lié à Flink, mais j'ai également trouvé ce problème dans Flink.

Pour les personnes utilisant Flink, vous devez télécharger Hadoop pré-groupé et le mettre à l'intérieur /opt/flink/lib.

David Magalhães
la source
-1

Je suis également tombé sur un problème similaire. Ajout de core-site.xml et hdfs-site.xml en tant que ressources de 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"));

Également édité des conflits de version dans pom.xml. (Par exemple, si la version configurée de hadoop est 2.8.1, mais dans le fichier pom.xml, les dépendances ont la version 2.7.1, changez-la en 2.8.1) Exécutez à nouveau l'installation de Maven.

Cette erreur a résolu pour moi.

Raxit Solanki
la source