Я пытаюсь запустить простой 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
.
Я думаю, что это из-за банок, есть идеи?
Это типичный случай, когда плагин 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-сборку
использовать объединенную версию всех объявлений служб FileSystem
, смотрите его ответ ниже.
Для тех, кто использует плагин тени, следующие по 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>
Это позволит объединить все орг."Апач".в Hadoop.ПС.Сервисы файловой системы в одном файле
Взял меня возрасты, чтобы разобраться с искровым 2.0.2, но здесь's мой бит:
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)
И соответствующие части моей сборки.СБТ`:
scalaVersion := "2.11.8"
libraryDependencies += "org.apache.spark" %% "spark-core" % "2.0.2"
Я надеюсь, что это может помочь!
Для записи, это все-таки происходит в 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>
благодаря david_p,скала
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>
Для Maven, просто добавьте зависимостей Maven для Hadoop-системы HDFS (см. ссылку ниже) будет решить эту проблему.
http://mvnrepository.com/artifact/org.apache.hadoop/hadoop-hdfs/2.7.1
Предполагается, что вы используете mvn и дистрибутив hadoop от cloudera. Я использую 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>
Я использую сборку СБТ упаковать мой проект. Я также встретиться с этой проблемой. Мое решение здесь. Шаг 1: добавить мета-инф mergestrategy в сборке.СБТ
case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard
case PathList("META-INF", ps @ _*) => MergeStrategy.first
Шаг 2: Добавить на Hadoop и HDFS lib для построения.СБТ
"org.apache.hadoop" % "hadoop-hdfs" % "2.4.0"
Шаг 3: очистить СБТ; сборка СБТ
Надеюсь, что выше информация может помочь вам.
Я предполагаю, что вы собираете образец с помощью maven.
Пожалуйста, проверьте содержимое JAR, который вы пытаетесь запустить. Особенно директорию META-INFO/services
, файл org.apache.hadoop.fs.FileSystem
. Там должен быть список классов реализации файловой системы. Проверьте наличие в списке строки org.apache.hadoop.hdfs.DistributedFileSystem
для HDFS и org.apache.hadoop.fs.LocalFileSystem
для локальной файловой схемы.
Если это так, вам необходимо переопределить указанный ресурс во время сборки.
Другая возможность - у вас просто нет hadoop-hdfs.jar
в вашем classpath, но вероятность этого мала. Обычно, если у вас корректная зависимость hadoop-client
, это не вариант.
Другая возможная причина (хоть и в ОПС вопрос не'т сама страдаю от этого) это если вы создаете экземпляр конфигурацию, которая не загружается по умолчанию:
Configuration config = new Configuration(false);
Если вы Don'т загрузить значения по умолчанию, то вы выиграли'т получить параметры по умолчанию, такие вещи, как файловая система
реализаций, что приводит к идентичным подобные ошибки при попытке доступа к файловой системе HDFS. Переход на конструктор без параметров передачи в "true", чтобы загрузить значения по умолчанию могут решить эту проблему.
Кроме того, при добавлении пользовательских мест конфигурации (например, в файловой системе) в конфигурации объекта
будьте осторожны, что перегрузка addResource ()
, который вы используете. Например, если вы используете `addResource(строка) тогда Hadoop и предполагает, что строка-это путь к классу ресурс, если вам нужно указать локальный файл, попробуйте следующее:
File configFile = new File("example/config.xml");
config.addResource(new Path("file://" + configFile.getAbsolutePath()));
Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://nameNode:9000");
FileSystem fs = FileSystem.get(conf);
набор ФС.defaultFS работает для меня! В Hadoop-2.8.1
Мне потребовалось некоторое время, чтобы выяснить, исправить даны ответы, из-за моего 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)
Я использую искру 2.1
И у меня эта часть в моем построении.СБТ`
assemblyMergeStrategy in assembly := {
case PathList("META-INF", xs @ _*) => MergeStrategy.discard
case x => MergeStrategy.first
}
Для использования СБТ ниже mergeStrategy в строй.СБТ
mergeStrategy in assembly <<= (mergeStrategy in assembly) { (old) => {
case PathList("META-INF", "services", "org.apache.hadoop.fs.FileSystem") => MergeStrategy.filterDistinctLines
case s => old(s)
}
}
Я столкнулся с той же проблемой. Я нашел два решения: (1) Для редактирования jar-файл вручную:
Открыть файл jar с помощью WinRAR (или подобные инструменты). Перейти к мета-инфо > обслуживание и редактирование "в орг."Апач".в Hadoop.ПС.Файловая система" с добавлением:
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>
Если вы используете СБТ:
//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
)
Я тоже сталкивался с подобной проблеме. Добавлено core-site.xml и hdfs-site.xml как ресурсы конф (объекта)
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 снова установить.
Эта ошибка решена для меня.
Использовать этот плагин
<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>