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


96

Я намагаюся запустити простий 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

Я думаю це через банки, будь-які ідеї?


Потрібна додаткова інформація ...
Тарік

2
Сам не знаю, але швидкий погляд на Google припускає, що є деякі проблеми навколо банок, на які не посилаються, як ви запропонували. Можливо, наступні посилання дадуть відповідь. groups.google.com/a/cloudera.org/forum/#!topic/scm-users/… grokbase.com/t/cloudera/cdh-user/134r64jm5t/…
Еміль

Я додав hadoop-common-2.0.0-cdh4.3.0-sources.jar та hadoop-core-0.20.2.jar до шляху до класу, я видалив спочатку, і це спрацювало, не знаю чому.
Mahender Singh

1
Хм .. Чи не могли б ви розповісти мені про своє оточення? Також, будь ласка, покажіть мені повне повідомлення про виключення.
Тарік

У чому цінність modelPath? ви пробувалиfile:///path/to/dir
Chris White

Відповіді:


174

Це типовий випадок, коли maven-assemblyплагін ламає речі.

Чому це сталося саме з нами

Кожен із різних файлів JAR ( hadoop-commonsдля LocalFileSystem, hadoop-hdfsдля DistributedFileSystem) містить різні файли, що викликаються org.apache.hadoop.fs.FileSystemв їх META-INFO/servicesкаталозі. Цей файл містить перелік канонічних назв класів реалізацій файлової системи, які вони хочуть оголосити (це називається Інтерфейс постачальника послуг, реалізований через java.util.ServiceLoader, див. org.apache.hadoop.FileSystem#loadFileSystems).

Коли ми використовуємо 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декларацій служб, ознайомтеся з його відповіддю нижче.


13
Ось еквівалентний код, необхідний для того, щоб робити те саме в 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)
Філіп О.

8
Власне, я щойно додав цю залежність http://mvnrepository.com/artifact/org.apache.hadoop/hadoop-hdfs/2.2.0maven до maven і вирішив проблему.
B.Mr.W.

6
Я спробував додати hadoop-hdfs, hadoop-core, hadoop-common, hadoop-client, а також спробував додати hadoopConfig.set ("fs.hdfs.impl", org.apache.hadoop.hdfs.DistributedFileSystem.class.getName () ); hadoopConfig.set ("fs.file.impl", org.apache.hadoop.fs.LocalFileSystem.class.getName ()); але не працює, при запуску від eclipse він працює нормально, але при запуску від команди java -cp відображається вище помилка
Harish Pathak

1
Харіш, що ти бачив? Тут та сама проблема, але з intellij
ThommyH

Просто доповнення до чудової відповіді: якщо ви використовуєте hadoop JARS, але виконуєте роботу в нехадопському кластері, "" "hadoopConfig.set (" fs.hdfs.impl ..... "" "" не буде робота. У цьому випадку ми повернемося до управління збіркою збірки, наприклад, у sbt ми можемо зробити стратегію злиття concat або навіть filterDistinctLines
людина

62

Для тих, хто використовує плагін shadow, дотримуючись порад david_p, ви можете об’єднати служби в затіненому jar, додавши 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 в один файл


3
Мені найбільше подобається це рішення. Вирішіть проблему у джерелі (збірці), а не виправляйте її змінами конфігурації.
Кевін Паулі,

1
Чудова відповідь. Виправлено мою подібну помилку. Пробував з Maven-Assembly-Plugin, а також комбінацією maven-jar-plugin / maven-dependency-plugin, але не працював. Це рішення змусило мою програму Spark працювати. Дуже дякую!
somnathchakrabarti

Чудова відповідь! Дуже дякую!
andrea.lagala

Це слід позначити як прийняту відповідь. ServicesResourceTransformer необхідний, коли jar-файли відображають інтерфейси до реалізацій за допомогою каталогу META-INF / services. Більше інформації можна знайти тут: maven.apache.org/plugins/maven-shade-plugin/examples/…
Маріо

Відмінна відповідь.
Ніранджан Субраманіан

9

Для протоколу це все ще відбувається в 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

дякую 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>

1
Лише прочитавши це, я зрозумів, що конф. Тут - конфігурація Hadoop: brucebcampbell.wordpress.com/2014/12/11/…
Саль

8

Мені знадобився вік, щоб зрозуміти це за допомогою 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

Якщо припустити, що ви використовуєте 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

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

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

Крок 2: додайте hadoop-hdfs lib до build.sbt

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

Крок 3: sbt чистий; збірка sbt

Сподіваюся, вищевказана інформація може вам допомогти.


15
Кращим рішенням може бути злиття, наприклад: case PathList("META-INF", "services", "org.apache.hadoop.fs.FileSystem") => MergeStrategy.filterDistinctLinesЦе збереже всі зареєстровані файлові системи
ravwojdyla

Дякую в @ravwojdyla, досить акуратне рішення. Ти врятував моє волосся. Для загублених душ, які виявили цю відповідь на іскру апачів. Додайте це до build.sbt, коли sbt-Assembly працює правильно.
Greedy Coder

Рішення, надане @ravwojdyla, єдине, що працювало для мене.
Сергій Ковальов

2
Рішення, надане @ravwojdyla, є ідеальним. Я зробив подібне налаштування в build.sbt і використовував: `` AssemblyMergeStrategy in Assembly: = {case PathList ("META-INF", "MANIFEST.MF") => MergeStrategy.discard case PathList ("META-INF", "services", "org.apache.hadoop.fs.FileSystem") => MergeStrategy.concat справа _ => MergeStrategy.first} `` `
людина

2

Я припускаю, що ви збираєте зразок за допомогою maven.

Перевірте вміст JAR, який ви намагаєтеся запустити. Особливо META-INFO/servicesкаталог, файл org.apache.hadoop.fs.FileSystem. Повинен бути список класів реалізації filsystem. Рядок перевірки org.apache.hadoop.hdfs.DistributedFileSystemприсутній у списку для HDFS та org.apache.hadoop.fs.LocalFileSystemдля локальної файлової схеми.

Якщо це так, вам доведеться замінити перенаправлений ресурс під час побудови.

Інша можливість полягає в тому, що ви просто не маєте hadoop-hdfs.jarсвого курсу занять, але це має низьку ймовірність. Зазвичай, якщо у вас правильна hadoop-clientзалежність, це не варіант.


HI Roman ..i має таку ж проблему, а META-INFO / services / org.apache.hadoop.fs.FileSystem не має рядка hdfs. У мене 2.0.0-mr1-cdh4.4.0 як єдина залежність. Що мені потрібно робити? Будь-яка документація з цього приводу? Використання Maven для побудови
sethi

2

Інша можлива причина (хоча саме питання 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()));

1

Мені знадобилось колись, щоб з’ясувати виправлення з поданих відповідей, завдяки моїй новизні. Це те, що я придумав, якщо комусь іншому потрібна допомога з самого початку:

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
Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://nameNode:9000");
FileSystem fs = FileSystem.get(conf);

set fs.defaultFS працює для мене! Hadoop-2.8.1


1

Для 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

Використовуйте цей плагін

<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

Якщо ви використовуєте 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

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

Відкрийте файл jar за допомогою WinRar (або подібних інструментів). Перейдіть до Meta-info> послуги та відредагуйте "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>


-1

Я теж натрапив на подібне питання. Додано 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 install.

Це вирішило помилку для мене.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.