hadoop
バージョン2.7
のFileUtil
には、複数のファイルを新しいファイルにマージするcopyMerge
関数があることを知っています。
ただし、copyMerge
関数は、3.0
バージョンのAPIごとにサポートされなくなりました。
ディレクトリ内のすべてのファイルを3.0
バージョンのhadoopの新しい単一ファイルにマージする方法に関するアイデアはありますか?
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を返し、エラーの場合はゼロ以外を返します。
同じ質問があり、copyMergeを再実装する必要がありました(ただしPySparkで、ただし元のcopyMergeと同じAPI呼び出しを使用しています)。
Hadoop 3に同等の機能がない理由がわかりません。HDFSディレクトリのファイルをHDFSファイルに頻繁にマージする必要があります。
上記のpySparkでの実装 https://github.com/Tagar/stuff/blob/master/copyMerge.py
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
}