web-dev-qa-db-ja.com

スキーム用のhadoop No FileSystem:file

Hadoopを使用して簡単なNaiveBayesClassiferを実行しようとしていますが、このエラーが発生します

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

ジャーのせいだと思いますか?

82
Mahender Singh

これは、maven-Assemblyプラグインが問題を引き起こす典型的なケースです。

なぜこれが私たちに起こったのか

さまざまなJAR(hadoop-commons for LocalFileSystemhadoop-hdfs for DistributedFileSystem)にはそれぞれ、org.Apache.hadoop.fs.FileSystemディレクトリにMETA-INFO/servicesという異なるファイルが含まれています。このファイルは、宣言したいファイルシステム実装の正規のクラス名をリストします(これは、Java.util.ServiceLoaderを介して実装されるサービスプロバイダーインターフェイスと呼ばれます。org.Apache.hadoop.FileSystem行2622 を参照)。

maven-Assembly-pluginを使用すると、すべてのJARが1つにマージされ、すべてのMETA-INFO/services/org.Apache.hadoop.fs.FileSystemが互いに上書きします。これらのファイルの1つだけが残ります(最後に追加されたファイル)。この場合、hadoop-commonsFileSystemリストは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>
159
david_p

シェードプラグインを使用している場合は、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サービスが1つのファイルにマージされます

54
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の場合、hadoop-hdfsのMaven依存関係を追加するだけで(以下のリンクを参照)、問題が解決します。

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

6
kwky

Sbt Assemblyを使用してプロジェクトをパッケージ化します。私もこの問題に直面しています。私の解決策はこちらです。ステップ1:build.sbtにMETA-INF mergestrategyを追加

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 clean; sbtアセンブリ

上記の情報がお役に立てば幸いです。

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。 filsystem実装クラスのリストがあるはずです。行org.Apache.hadoop.hdfs.DistributedFileSystemがHDFSのリストにあり、org.Apache.hadoop.fs.LocalFileSystemがローカルファイルスキームにあることを確認します。

この場合、ビルド中に参照されたリソースをオーバーライドする必要があります。

他の可能性としては、クラスパスにhadoop-hdfs.jarがないだけですが、これは低い確率です。通常、正しいhadoop-client依存関係がある場合、これはオプションではありません。

2

SBTの場合、build.sbtの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
Asad Raza

私の初心者のため、与えられた答えから修正を見つけるのに時間がかかりました。他の誰かが最初から助けを必要とする場合、これは私が思いついたものです:

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