hadoop Nessun FileSystem per schema: file


96

Sto cercando di eseguire un semplice NaiveBayesClassiferutilizzo di hadoop, ottenendo questo errore

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)

Codice :

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

modelPathpunta a un NaiveBayes.binfile e l'oggetto di configurazione sta stampando -Configuration: core-default.xml, core-site.xml

Penso che sia a causa dei barattoli, qualche idea?


Hai bisogno di ulteriori informazioni ...
Tariq

2
Non mi conosco, ma una rapida occhiata su Google suggerisce che ci sono alcuni problemi relativi ai barattoli che non vengono referenziati come suggerito. Forse i seguenti link daranno una risposta. groups.google.com/a/cloudera.org/forum/#!topic/scm-users/… grokbase.com/t/cloudera/cdh-user/134r64jm5t/…
Emile

Stavo aggiungendo hadoop-common-2.0.0-cdh4.3.0-sources.jar e hadoop-core-0.20.2.jar al percorso di classe, ho rimosso prima e ha funzionato, non so perché.
Mahender Singh

1
Hmm ... Potresti parlarmi del tuo ambiente? Inoltre, mostrami il messaggio di eccezione completo.
Tariq

Qual è il valore di modelPath? hai provatofile:///path/to/dir
Chris White

Risposte:


174

Questo è un tipico caso del maven-assemblyplugin che rompe le cose.

Perché questo è successo a noi

Diversi JAR ( hadoop-commonsper LocalFileSystem, hadoop-hdfsper DistributedFileSystem) contengono ciascuno un file diverso chiamato org.apache.hadoop.fs.FileSystemnella loro META-INFO/servicesdirectory. Questo file elenca i nomi di classe canonici delle implementazioni del filesystem che vogliono dichiarare (questa è chiamata interfaccia del provider di servizi implementata tramite java.util.ServiceLoader, vedere org.apache.hadoop.FileSystem#loadFileSystems).

Quando lo usiamo maven-assembly-plugin, unisce tutti i nostri JAR in uno e tutti si META-INFO/services/org.apache.hadoop.fs.FileSystemsovrascrivono a vicenda. Rimane solo uno di questi file (l'ultimo che è stato aggiunto). In questo caso, l' FileSystemelenco da hadoop-commonssovrascrive l'elenco da hadoop-hdfs, quindi DistributedFileSystemnon è stato più dichiarato.

Come l'abbiamo risolto

Dopo aver caricato la configurazione di Hadoop, ma appena prima di fare qualsiasi cosa FileSystemcorrelata, chiamiamo questo:

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

Aggiornamento: la soluzione corretta

È stato portato alla mia attenzione dal fatto krookedkingche esiste un modo basato sulla configurazione per rendere l' maven-assemblyuso una versione unita di tutte le FileSystemdichiarazioni dei servizi, controlla la sua risposta di seguito.


13
Ecco il codice equivalente richiesto per fare la stessa cosa in 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
In realtà, ho appena aggiunto questa dipendenza http://mvnrepository.com/artifact/org.apache.hadoop/hadoop-hdfs/2.2.0maven a maven e il problema è stato risolto.
B.Mr.W.

6
Ho provato ad aggiungere hadoop-hdfs, hadoop-core, hadoop-common, hadoop-client, Aslo ha provato ad aggiungere hadoopConfig.set ("fs.hdfs.impl", org.apache.hadoop.hdfs.DistributedFileSystem.class.getName () ); hadoopConfig.set ("fs.file.impl", org.apache.hadoop.fs.LocalFileSystem.class.getName ()); ma non funziona, quando si esegue da eclipse funziona bene ma quando si esegue dal comando java -cp mostra l'errore precedente
Harish Pathak

1
Harish, cosa hai visto? Stesso problema qui ma con intellij
ThommyH

Solo un'aggiunta alla meravigliosa risposta: se si usa hadoop JARS ma si esegue il lavoro in un cluster non hadoop, "" "hadoopConfig.set (" fs.hdfs.impl ..... "" "" non lo farà work. In tal caso ricorreremo alla gestione della build dell'assembly. ad esempio in sbt potremmo fare una strategia di unione di concat o anche filterDistinctLines
human

62

Per coloro che utilizzano il plug-in ombra, seguendo il consiglio di david_p, è possibile unire i servizi nel jar ombreggiato aggiungendo ServicesResourceTransformer alla configurazione del plug-in:

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

Questo unirà tutti i servizi org.apache.hadoop.fs.FileSystem in un unico file


3
Mi piace di più questa soluzione. Risolvi il problema alla fonte (la build) piuttosto che correggerlo con modifiche alla configurazione dopo il fatto.
Kevin Pauli

1
Bella risposta. Risolto il mio errore simile. Ho provato con la combinazione maven-assembly-plugin e maven-jar-plugin / maven-dependency-plugin ma non ha funzionato. Questa soluzione ha fatto funzionare la mia app Spark. Molte grazie!
somnathchakrabarti

Bella risposta! Molte grazie!
andrea.lagala

Questo dovrebbe essere contrassegnato come risposta accettata. ServicesResourceTransformer è necessario quando i file jar associano le interfacce alle implementazioni utilizzando una directory META-INF / services. Maggiori informazioni possono essere trovate qui: maven.apache.org/plugins/maven-shade-plugin/examples/…
Mario

Ottima risposta.
Niranjan Subramanian

9

Per la cronaca, questo sta ancora accadendo in hadoop 2.4.0. Così frustrante...

Sono stato in grado di seguire le istruzioni in questo link: http://grokbase.com/t/cloudera/scm-users/1288xszz7r/no-filesystem-for-scheme-hdfs

Ho aggiunto quanto segue al mio core-site.xml e ha funzionato:

<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

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

o

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

1
Solo dopo ho letto questo fatto mi rendo conto che il conf qui era la configurazione Hadoop: brucebcampbell.wordpress.com/2014/12/11/...
Sal

8

Mi ci sono voluti anni per capirlo con Spark 2.0.2, ma ecco la mia parte:

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)

E le parti rilevanti del mio build.sbt:

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

Spero che questo possa aiutare!



5

Supponendo che tu stia utilizzando mvn e cloudera distribuzione di hadoop. Sto usando cdh4.6 e l'aggiunta di queste dipendenze ha funzionato per me. Penso che dovresti controllare le versioni delle dipendenze hadoop e 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>

non dimenticare di aggiungere il repository cloudera mvn.

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

4

Uso l'assembly sbt per impacchettare il mio progetto. Incontro anche questo problema. La mia soluzione è qui. Passaggio 1: aggiungi la strategia di fusione META-INF nel tuo file build.sbt

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

Passaggio 2: aggiungi hadoop-hdfs lib a build.sbt

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

Step3: sbt clean; assemblaggio sbt

Spero che le informazioni di cui sopra possano aiutarti.


15
Una soluzione migliore potrebbe essere quella di unire come: case PathList("META-INF", "services", "org.apache.hadoop.fs.FileSystem") => MergeStrategy.filterDistinctLinesCiò manterrà tutti i filesystem registrati
ravwojdyla

Grazie a @ravwojdyla, soluzione piuttosto carina. Mi hai salvato i capelli. Per le anime perdute che scoprono questa risposta per Apache Spark. Aggiungilo a build.sbt quando sbt-assembly funziona correttamente.
Greedy Coder

La soluzione fornita da @ravwojdyla è l'unica che ha funzionato per me.
Sergey Kovalev

2
La soluzione data da @ravwojdyla è l'ideale. Ho eseguito una configurazione simile in build.sbt e ho utilizzato: `` 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} `` `
umano

2

Presumo che tu costruisca un campione usando Maven.

Controlla il contenuto del JAR che stai tentando di eseguire. Soprattutto META-INFO/servicesdirectory, file org.apache.hadoop.fs.FileSystem. Dovrebbe esserci un elenco di classi di implementazione del file system. La linea di controllo org.apache.hadoop.hdfs.DistributedFileSystemè presente nell'elenco per HDFS e org.apache.hadoop.fs.LocalFileSystemper lo schema di file locale.

Se questo è il caso, devi sovrascrivere la risorsa indicata durante la compilazione.

Un'altra possibilità è che semplicemente non hai hadoop-hdfs.jarnel tuo classpath ma questo ha una bassa probabilità. Di solito, se hai una hadoop-clientdipendenza corretta, non è un'opzione.


HI Roman ..i ho lo stesso problema e META-INFO / services / org.apache.hadoop.fs.FileSystem non ha la linea hdfs. Ho 2.0.0-mr1-cdh4.4.0 come unica dipendenza. Cosa devo fare? Qualche documentazione su questo? Utilizzo di Maven per la costruzione
sethi

2

Un'altra possibile causa (sebbene la questione degli OP non ne risenta di per sé) è se crei un'istanza di configurazione che non carica i valori predefiniti:

Configuration config = new Configuration(false);

Se non carichi i valori predefiniti, non otterrai le impostazioni predefinite per cose come le FileSystemimplementazioni che portano a errori identici come questo quando si tenta di accedere a HDFS. Il passaggio al costruttore senza parametri del passaggio trueper caricare i valori predefiniti può risolvere questo problema.

Inoltre, se stai aggiungendo posizioni di configurazione personalizzate (ad esempio sul file system) Configurationall'oggetto, fai attenzione a quale sovraccarico addResource()utilizzi. Ad esempio, se si utilizza, addResource(String)Hadoop presume che la stringa sia una risorsa del percorso di classe, se è necessario specificare un file locale, provare quanto segue:

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

1

Mi ci è voluto un po 'di tempo per capire la soluzione dalle risposte date, a causa della mia novità. Questo è quello che ho pensato, se qualcun altro ha bisogno di aiuto fin dall'inizio:

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)

Sto usando Spark 2.1

E ho questa parte nel mio 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 funziona per me! Hadoop-2.8.1


1

Per SBT utilizzare di seguito 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

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

Se stai usando 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
)

0

Ho affrontato lo stesso problema. Ho trovato due soluzioni: (1) Modifica manualmente il file jar:

Apri il file jar con WinRar (o strumenti simili). Vai a Meta-info> servizi e modifica "org.apache.hadoop.fs.FileSystem" aggiungendo:

org.apache.hadoop.fs.LocalFileSystem

(2) Modificare l'ordine delle mie dipendenze come segue

<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

Questo non è correlato a Flink, ma ho riscontrato questo problema anche in Flink.

Per le persone che utilizzano Flink, è necessario scaricare Hadoop pre-bundle e inserirlo /opt/flink/lib.


-1

Mi sono anche imbattuto in un problema simile. Aggiunti core-site.xml e hdfs-site.xml come risorse di conf (oggetto)

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

Anche i conflitti di versione modificati in pom.xml. (ad esempio, se la versione configurata di hadoop è 2.8.1, ma nel file pom.xml, dependancies ha la versione 2.7.1, quindi modificala in 2.8.1) Esegui di nuovo l'installazione di Maven.

Questo errore ha risolto per me.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.