web-dev-qa-db-ja.com

Hadoop 3.0でCopyMergeを行う方法

hadoopバージョン2.7FileUtilには、複数のファイルを新しいファイルにマージするcopyMerge関数があることを知っています。

ただし、copyMerge関数は、3.0バージョンのAPIごとにサポートされなくなりました。

ディレクトリ内のすべてのファイルを3.0バージョンのhadoopの新しい単一ファイルにマージする方法に関するアイデアはありますか?

12
Jeremy

FileUtil#copyMergeメソッドが削除されました。主要な変更の詳細を見る:

https://issues.Apache.org/jira/browse/HADOOP-12967

https://issues.Apache.org/jira/browse/HADOOP-11392

Getmergeを使用できます

使用法:hadoop fs -getmerge [-nl]

ソースディレクトリと宛先ファイルを入力として受け取り、src内のファイルを宛先ローカルファイルに連結します。オプションで、各ファイルの末尾に改行文字(LF)を追加できるように-nlを設定できます。 -skip-empty-fileを使用すると、ファイルが空の場合に不要な改行文字を回避できます。

例:

hadoop fs -getmerge -nl /src /opt/output.txt
hadoop fs -getmerge -nl /src/file1.txt /src/file2.txt /output.txt

終了コード:成功した場合は0を返し、エラーの場合はゼロ以外を返します。

https://hadoop.Apache.org/docs/current/hadoop-project-dist/hadoop-common/FileSystemShell.html#getmerge

7
ravi

同じ質問があり、copyMergeを再実装する必要がありました(ただしPySparkで、ただし元のcopyMergeと同じAPI呼び出しを使用しています)。

Hadoop 3に同等の機能がない理由がわかりません。HDFSディレクトリのファイルをHDFSファイルに頻繁にマージする必要があります。

上記のpySparkでの実装 https://github.com/Tagar/stuff/blob/master/copyMerge.py

3
Tagar

FileUtil.copyMerge() は非推奨になり、バージョン3からAPIから削除されたため、簡単な解決策はそれを自分で再実装することです。

ここ は、以前のバージョンのJavaオリジナル実装です。

これはScalaの書き換えです:

import scala.util.Try
import org.Apache.hadoop.conf.Configuration
import org.Apache.hadoop.fs.{FileSystem, Path}
import org.Apache.hadoop.io.IOUtils
import Java.io.IOException

def copyMerge(
    srcFS: FileSystem, srcDir: Path,
    dstFS: FileSystem, dstFile: Path,
    deleteSource: Boolean, conf: Configuration
): Boolean = {

  if (dstFS.exists(dstFile))
    throw new IOException(s"Target $dstFile already exists")

  // Source path is expected to be a directory:
  if (srcFS.getFileStatus(srcDir).isDirectory()) {

    val outputFile = dstFS.create(dstFile)
    Try {
      srcFS
        .listStatus(srcDir)
        .sortBy(_.getPath.getName)
        .collect {
          case status if status.isFile() =>
            val inputFile = srcFS.open(status.getPath())
            Try(IOUtils.copyBytes(inputFile, outputFile, conf, false))
            inputFile.close()
        }
    }
    outputFile.close()

    if (deleteSource) srcFS.delete(srcDir, true) else true
  }
  else false
}
3
Xavier Guihot