1

我正在用 Java 编写一个归档程序。将归档的文件已经驻留在 HDFS 中。我需要能够将文件从 HDFS 中的一个位置移动到另一个位置,并使用 Gzip 压缩最终文件。要移动的文件可能非常大,因此使用 HDFS API 移动和压缩它们可能效率很低。所以我想我可以在我的代码中写一个 mapreduce 作业来为我做这件事。

但是,我一直找不到任何示例来说明如何使用 MapReduce API 复制这些文件并将它们以 gzip 格式输出。事实上,我什至很难找到一个编程示例,说明如何通过 mapreduce 在 HDFS 中复制文件。

任何人都可以阐明我如何使用 MapReduce API 完成此任务吗?

编辑:这是我到目前为止的工作配置代码,它改编自 Amar 给我的帮助:

        conf.setBoolean("mapred.output.compress", true); 
        conf.set("mapred.output.compression.codec","org.apache.hadoop.io.compress.GzipCodec");
        Job job = new Job(conf);
        job.setJarByClass(LogArchiver.class);
        job.setJobName("ArchiveMover_"+dbname);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);
        //job.setMapperClass(IdentityMapper.class);
        //job.setReducerClass(IdentityReducer.class);
        job.setInputFormatClass(NonSplittableTextInputFormat.class);
        job.setOutputFormatClass(TextOutputFormat.class);
        job.setNumReduceTasks(0);
        FileInputFormat.setInputPaths(job, new Path(archiveStaging+"/"+dbname+"/*/*"));
        FileOutputFormat.setOutputPath(job, new Path(archiveRoot+"/"+dbname));
        job.submit();

这是位于 LogArchiver 类中的 NonSplittableTextInputFormat 的类声明

public class NonSplittableTextInputFormat extends TextInputFormat {
    public NonSplittableTextInputFormat () {
    }

    @Override
    protected boolean isSplitable(JobContext context, Path file) {
        return false;
    }
}
4

1 回答 1

0

您可以使用和编写自定义 jar 实现。您可以生成 gzip 文件作为输出,而不是纯文本文件。在 中设置以下配置:IdentityMapperIdentityReducerrun()

conf.setBoolean("mapred.output.compress", true); 
conf.set("mapred.output.compression.codec","org.apache.hadoop.io.compress.GzipCodec");

为了确保输入和输出中的文件数量相同,只是输出文件必须经过 gzip 压缩,您必须做 2 件事:

  1. 实现 NonSplittableTextInputFormat
  2. 将减少任务设置为零。

为了确保每个映射器读取一个文件,您可以扩展TextInputFormat如下:

import org.apache.hadoop.fs.*;
import org.apache.hadoop.mapred.TextInputFormat;
public class NonSplittableTextInputFormat extends TextInputFormat {
    @Override
    protected boolean isSplitable(FileSystem fs, Path file) {
        return false;
    }
}

并将上述实现用作:

job.setInputFormatClass(NonSplittableTextInputFormat.class);

要将 reduce 任务设置为零,请执行以下操作:

job.setNumReduceTasks(0);

这将为您完成工作,但最后一件事是文件名不一样!但我相信,这里也必须有一个解决方法。

于 2013-02-14T18:24:54.950 回答