[java] 스키마에 대한 파일 시스템 없음 : 파일

나는 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..

modelPathNaiveBayes.bin파일을 가리키고 구성 개체가 인쇄 중입니다.Configuration: core-default.xml, core-site.xml

항아리 때문이라고 생각합니다. 아이디어가 있습니까?



답변

이것은 maven-assembly플러그인이 문제를 일으키는 전형적인 경우입니다 .

이것이 우리에게 일어난 이유

서로 다른 JAR ( hadoop-commonsfor LocalFileSystem, hadoop-hdfsfor 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-assemblyFileSystem


답변

shade 플러그인을 사용하는 경우 david_p의 조언에 따라 ServicesResourceTransformer를 플러그인 구성에 추가하여 음영 처리 된 jar의 서비스를 병합 할 수 있습니다.

  <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 서비스가 하나의 파일에 병합됩니다.


답변

기록을 위해 이것은 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, 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>


답변

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"

도움이 되었기를 바랍니다.


답변

maven의 경우 hadoop-hdfs (아래 링크 참조)에 대한 maven 종속성을 추가하면 문제가 해결됩니다.

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


답변

hadoop의 mvn 및 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>