Hasoop No FileSystem для схемы: файл

Я пытаюсь запустить простой 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

Я думаю, что это из-за банок, любых идей?

Ответ 1

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

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

Различные JAR файлы (hadoop-commons для LocalFileSystem, hadoop-hdfs для DistributedFileSystem) содержат в своем каталоге META-INFO/services отдельный файл с именем org.apache.hadoop.fs.FileSystem. В этом файле перечислены канонические имена классов реализаций файловой системы, которые они хотят объявить (это называется интерфейсом поставщика услуг, реализованным через 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 -related, мы вызываем это:

    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, посмотрите его ответ ниже.

Ответ 2

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

  <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 в одном файле

Ответ 3

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

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

Я добавил следующее к моему основному сайту .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>

Ответ 4

Мне приходилось разбираться с 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"

Надеюсь, это поможет!

Ответ 5

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

Предполагая, что вы используете 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>

Ответ 8

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

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

Шаг 2: добавьте hasoop-hdfs lib в build.sbt

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

Шаг 3: sbt clean; сборка sbt

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

Ответ 9

Я предполагаю, что вы создаете образец с помощью 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, это не вариант.

Ответ 10

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

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

Ответ 11

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

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
}

Ответ 12

Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://nameNode:9000");
FileSystem fs = FileSystem.get(conf);

set fs.defaultFS работает для меня! Hadoop-2.8.1

Ответ 13

Для использования 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)
  }
}

Ответ 14

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

Ответ 15

Для тех, кто использует Spark Java:

SparkSession session = SparkSession.builder().master("local[*]").getOrCreate();
session.sparkContext().hadoopConfiguration().set("fs.hdfs.impl", "org.apache.hadoop.hdfs.DistributedFileSystem");
session.sparkContext().hadoopConfiguration().set("fs.file.impl", "org.apache.hadoop.fs.LocalFileSystem");'''

Ответ 16

Я столкнулся с той же проблемой. Я нашел два решения: (1) Редактирование файла JAR вручную:

Откройте файл jar с помощью WinRar (или аналогичных инструментов). Перейдите в раздел Meta-info> services и измените "org.apache.hadoop.fs.FileSystem", добавив:

org.apache.hadoop.fs.LocalFileSystem

(2) Изменить порядок моих зависимостей следующим образом

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

Ответ 17

Используйте этот плагин

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

Ответ 18

Я также столкнулся с подобной проблемой. Добавлены core-site.xml и hdfs-site.xml в качестве ресурсов 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"));

Также отредактированы конфликты версий в pom.xml. (например, если настроенная версия hadoop равна 2.8.1, но в файле pom.xml зависимости имеют версию 2.7.1, а затем измените ее на 2.8.1) Запустите Maven еще раз.

Эта разрешенная ошибка для меня.