hadoop No FileSystem para esquema: archivo

Estoy intentando ejecutar un NaiveBayesClassifer simple usando hadoop, obteniendo este error

 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) 

Código:

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

modelPath apunta al archivo NaiveBayes.bin y el objeto de configuración está imprimiendo – Configuration: core-default.xml, core-site.xml

Creo que es por los flasks, ¿alguna idea?

Este es un caso típico del plugin maven-assembly rompe cosas.

Por qué nos pasó esto a nosotros

Diferentes hadoop-commons ( hadoop-commons para LocalFileSystem , hadoop-hdfs para DistributedFileSystem ) contienen cada uno un archivo diferente llamado org.apache.hadoop.fs.FileSystem en su directorio META-INFO/services . Este archivo enumera los nombres de clase canónicos de las implementaciones del sistema de archivos que desean declarar (Esto se denomina Interfaz de proveedor de servicios implementada a través de java.util.ServiceLoader , consulte la línea 2622 de org.apache.hadoop.FileSystem ).

Cuando usamos maven-assembly-plugin , fusiona todos nuestros JAR en uno, y todos los META-INFO/services/org.apache.hadoop.fs.FileSystem sobrescriben entre sí. Solo queda uno de estos archivos (el último que se agregó). En este caso, la lista FileSystem de hadoop-commons sobrescribe la lista de hadoop-hdfs , por lo que DistributedFileSystem ya no se declaró.

Cómo lo arreglamos

Después de cargar la configuración de Hadoop, pero justo antes de hacer algo relacionado con FileSystem , llamamos a esto:

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

Actualización: la solución correcta

Se me ha llamado la atención por el +krookedking que existe una forma basada en la configuración para hacer que el maven-assembly utilice una versión fusionada de todas las declaraciones de servicios de FileSystem . Agregue el siguiente complemento a su archivo pom.xml :

  org.apache.maven.plugins maven-shade-plugin 2.3   package  shade          

Para aquellos que usan el plugin de sombreado, siguiendo el consejo de david_p, pueden fusionar los servicios en el jarrón sombreado agregando ServicesResourceTransformer a la configuración del complemento:

   org.apache.maven.plugins maven-shade-plugin 2.3   package  shade          

Esto combinará todos los servicios de org.apache.hadoop.fs.FileSystem en un archivo

Para el registro, esto todavía está sucediendo en hadoop 2.4.0. Muy frustrante…

Pude seguir las instrucciones en este enlace: http://grokbase.com/t/cloudera/scm-users/1288xszz7r/no-filesystem-for-scheme-hdfs

Agregué lo siguiente a mi core-site.xml y funcionó:

  fs.file.impl org.apache.hadoop.fs.LocalFileSystem The FileSystem for file: uris.   fs.hdfs.impl org.apache.hadoop.hdfs.DistributedFileSystem The FileSystem for hdfs: uris.  

gracias 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

  fs.hdfs.impl org.apache.hadoop.hdfs.DistributedFileSystem  

Me llevó años descubrirlo con Spark 2.0.2, pero aquí está mi 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) 

Y las partes relevantes de mi build.sbt :

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

¡Espero que esto pueda ayudar!

Para maven, solo agregue la dependencia de maven para hadoop-hdfs (consulte el siguiente enlace) que resolverá el problema.

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

Suponiendo que está utilizando la distribución mvn y cloudera de hadoop. Estoy usando cdh4.6 y agregar estas dependencias funcionó para mí. Creo que debería verificar las versiones de las dependencias de hadoop y mvn.

  org.apache.hadoop hadoop-core 2.0.0-mr1-cdh4.6.0   org.apache.hadoop hadoop-common 2.0.0-cdh4.6.0   org.apache.hadoop hadoop-client 2.0.0-cdh4.6.0  

no te olvides de agregar el repository cloudera mvn.

  cloudera https://repository.cloudera.com/artifactory/cloudera-repos/  

Yo uso sbt assembly para empacar mi proyecto. También me encuentro con este problema. Mi solución está aquí. Paso 1: agrega META-INF mergestrategy en tu build.sbt

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

Paso 2: agrega hadoop-hdfs lib a build.sbt

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

Paso 3: sbt clean; sbt asamblea

Espero que la información anterior te pueda ayudar.

Supongo que construyes una muestra usando Maven.

Verifique el contenido del archivo JAR que intenta ejecutar. Especialmente META-INFO/services directorio de META-INFO/services , archivo org.apache.hadoop.fs.FileSystem . Debería haber una lista de clases de implementación del sistema fils. Ver línea org.apache.hadoop.hdfs.DistributedFileSystem está presente en la lista para HDFS y org.apache.hadoop.fs.LocalFileSystem para el esquema de archivo local.

Si este es el caso, debe anular el recurso referido durante la comstackción.

Otra posibilidad es que simplemente no tenga hadoop-hdfs.jar en su classpath pero esto tiene baja probabilidad. Por lo general, si tiene una hadoop-client correcta de hadoop-client no es una opción.

Otra posible causa (aunque la pregunta de OP no se resiente) es si crea una instancia de configuración que no carga los valores predeterminados:

 Configuration config = new Configuration(false); 

Si no carga los valores predeterminados, no obtendrá la configuración predeterminada para cosas como las implementaciones de FileSystem , lo que conduce a errores idénticos como este al intentar acceder a HDFS. Cambiar al constructor sin parámetros de paso en true para cargar los valores predeterminados puede resolver esto.

Además, si agrega ubicaciones de configuración personalizadas (por ejemplo, en el sistema de archivos) al objeto Configuration tenga cuidado con la sobrecarga de addResource() que utiliza. Por ejemplo, si usa addResource(String) , Hadoop asume que la cadena es un recurso de ruta de clase, si necesita especificar un archivo local, intente lo siguiente:

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

Me llevó algún tiempo encontrar la solución a partir de las respuestas dadas, debido a mi novedad. Esto es lo que se me ocurrió, si alguien más necesita ayuda desde el principio:

 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) 

Estoy usando Spark 2.1

Y tengo esta parte en mi build.sbt

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

establecer fs.defaultFS funciona para mí! Hadoop-2.8.1

Si está utilizando 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 ) 

También me encontré con un problema similar. Se agregaron core-site.xml y hdfs-site.xml como recursos de conf (objeto)

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

También conflictos de versión editados en pom.xml. (Por ejemplo, si la versión configurada de hadoop es 2.8.1, pero en el archivo pom.xml, dependencias tiene la versión 2.7.1, luego cámbialo a 2.8.1) Ejecuta Maven instala de nuevo.

Esto me solucionó el error.

Para usar SBT debajo de mergeStrategy en 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) } } 

Use este plugin

  org.apache.maven.plugins maven-shade-plugin 1.5   package  shade     *:*  META-INF/*.SF META-INF/*.DSA META-INF/*.RSA    true allinone   *:*     reference.conf