it-roy-ru.com

hadoop Нет файловой системы для схемы: файл

Я пытаюсь запустить простой NaiveBayesClassifer, используя hadoop, получаю эту ошибку

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)

Код: 

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

modelPath указывает на файл NaiveBayes.bin, а объект конфигурации печатает - Configuration: core-default.xml, core-site.xml 

Я думаю это из-за банок, есть идеи?

76
Mahender Singh

Это типичный случай, когда плагин maven-Assembly ломает вещи.

Почему это случилось с нами

Различные JAR-файлы (hadoop-commons для LocalFileSystem, hadoop-hdfs для DistributedFileSystem) содержат разные файлы с именем org.Apache.hadoop.fs.FileSystem в своем каталоге META-INFO/services. В этом файле перечислены канонические имена классов реализаций файловой системы, которые они хотят объявить (это называется интерфейсом поставщика услуг, реализованным через Java.util.ServiceLoader, см. org.Apache.hadoop.FileSystemстрока 2622 ).

Когда мы используем maven-Assembly-plugin, он объединяет все наши JAR-файлы в один, и все META-INFO/services/org.Apache.hadoop.fs.FileSystem перезаписывают друг друга. Остается только один из этих файлов (последний, который был добавлен). В этом случае список FileSystem из hadoop-commons перезаписывает список из hadoop-hdfs, поэтому DistributedFileSystem больше не объявляется.

Как мы это исправили

После загрузки конфигурации Hadoop, но перед тем, как делать что-либо, связанное с FileSystem, мы вызываем это:

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

Обновление: правильное исправление

+krookedking привлек мое внимание к тому, что есть способ на основе конфигурации заставить maven-Assembly использовать объединенную версию всех объявлений служб FileSystem . Добавьте следующий плагин в свой файл pom.xml:

<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

Для тех, кто использует плагин shade, следуя совету david_p, вы можете объединить сервисы в затененном фляге, добавив ServicesResourceTransformer в конфигурацию плагина:

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

Это объединит все службы org.Apache.hadoop.fs.FileSystem в один файл.

52
krookedking

Для записи, это все еще происходит в hadoop 2.4.0. Так расстраивает ...

Я смог следовать инструкциям по этой ссылке: http://grokbase.com/t/cloudera/scm-users/1288xszz7r/no-filesystem-for-scheme-hdfs

Я добавил следующее в свой core-site.xml, и это сработало:

<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

спасибо 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);

или же

<property>
 <name>fs.hdfs.impl</name>
 <value>org.Apache.hadoop.hdfs.DistributedFileSystem</value>
</property>
7
Andy

Мне понадобилось много времени, чтобы понять это с помощью Spark 2.0.2, но вот мой кусочек:

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)

И соответствующие части моего build.sbt:

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

Я надеюсь, что это может помочь!

7
Mauro Arnoldi

Для maven, просто добавьте зависимость maven для hadoop-hdfs (см. Ссылку ниже), чтобы решить эту проблему.

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

5
kwky

Я использую sbt Assembly для упаковки своего проекта. Я тоже сталкиваюсь с этой проблемой. Мое решение здесь. Step1: добавьте META-INF mergestrategy в ваш build.sbt

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

Шаг 2: добавьте библиотеку hadoop-hdfs в build.sbt

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

Шаг 3: чистое свт; сборка

Надеюсь, что приведенная выше информация может помочь вам.

4
Haimei

Предполагается, что вы используете mvn и cloudera для распределения hadoop. Я использую cdh4.6 и добавление этих зависимостей сработало для меня. Я думаю, что вы должны проверить версии зависимостей hadoop и 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>

не забудьте добавить хранилище cloudera mvn.

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

Другая возможная причина (хотя сам вопрос OP от этого не страдает) - если вы создаете экземпляр конфигурации, который не загружает значения по умолчанию:

Configuration config = new Configuration(false);

Если вы не загрузите настройки по умолчанию, вы не получите настройки по умолчанию для таких вещей, как реализации FileSystem, которые приводят к таким же ошибкам, как эта, при попытке доступа к HDFS. Переключение на конструктор без параметров с передачей true для загрузки значений по умолчанию может решить эту проблему.

Кроме того, если вы добавляете пользовательские расположения конфигурации (например, в файловой системе) к объекту Configuration, будьте осторожны с тем, какую перегрузку addResource() вы используете. Например, если вы используете addResource(String), то Hadoop предполагает, что строка является ресурсом пути к классам, если вам нужно указать локальный файл, попробуйте следующее:

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

Я предполагаю, что вы строите образец, используя Maven.

Пожалуйста, проверьте содержимое JAR, который вы пытаетесь запустить. Особенно META-INFO/services каталог, файл org.Apache.hadoop.fs.FileSystem. Должен быть список классов реализации файловой системы. Проверьте, что строка org.Apache.hadoop.hdfs.DistributedFileSystem присутствует в списке для HDFS и org.Apache.hadoop.fs.LocalFileSystem для локальной схемы файлов.

Если это так, вы должны переопределить указанный ресурс во время сборки.

Другая возможность - у вас просто нет hadoop-hdfs.jar в вашем пути к классам, но это маловероятно. Обычно, если у вас правильная зависимость hadoop-client, это не вариант.

2
Roman Nikitchenko

Мне понадобилось некоторое время, чтобы выяснить, из каких ответов я получил ответ, из-за моей новизны. Вот что я придумал, если кому-то еще нужна помощь с самого начала:

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)

Я использую Spark 2.1

И у меня есть эта часть в моем 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! Hadoop-2.8.1

1
Asran Deng

Если вы используете 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
Peluo

Для SBT используйте ниже mergeStrategy в 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