Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用MapReduce API通过Gzip压缩复制HDFS中的文件_Map_Copy_Mapreduce_Gzip_Reduce - Fatal编程技术网

使用MapReduce API通过Gzip压缩复制HDFS中的文件

使用MapReduce API通过Gzip压缩复制HDFS中的文件,map,copy,mapreduce,gzip,reduce,Map,Copy,Mapreduce,Gzip,Reduce,我正在用Java编写一个归档程序。将要存档的文件已驻留在HDFS中。我需要能够将文件从HDFS中的一个位置移动到另一个位置,并使用Gzip压缩最终文件。要移动的文件可能相当大,因此使用HDFSAPI来移动和压缩它们可能会非常低效。所以我想我可以在我的代码中写一个mapreduce作业来帮我完成 但是,我找不到任何示例来说明如何使用MapReduceAPI复制这些文件并以gzip格式输出。事实上,我甚至很难找到一个编程示例,说明如何通过mapreduce复制HDFS中的文件 有人能告诉我如何使用M

我正在用Java编写一个归档程序。将要存档的文件已驻留在HDFS中。我需要能够将文件从HDFS中的一个位置移动到另一个位置,并使用Gzip压缩最终文件。要移动的文件可能相当大,因此使用HDFSAPI来移动和压缩它们可能会非常低效。所以我想我可以在我的代码中写一个mapreduce作业来帮我完成

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

有人能告诉我如何使用MapReduceAPI实现这一点吗

编辑:这是我到目前为止的作业配置代码,它是根据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;
    }
}
您可以使用IdentityMapper和IdentityReducer编写一个。 您可以生成gzip文件作为输出,而不是纯文本文件。在运行中设置以下配置:

为了确保输入和输出中的文件数相同,仅输出文件必须gzip,您必须做两件事:

实现不可分割的TextInputFormat 将reducetasks设置为零。 为了确保每个映射器读取一个文件,您可以按如下方式扩展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 tasks设置为零,请执行以下操作:

job.setNumReduceTasks(0);

这将为您完成工作,但最后一件事,文件名将不一样!但我也确信这一点,这附近一定有一项工作。

不确定这是否有帮助,但您是否研究过Hadoop流媒体?很可能我需要求助于此,但我更喜欢通过MapReduce API来实现。我试试看。再次感谢!你确实让我朝着我的目标走了很长一段路。我现在只有两个问题。1假设我有一个这样的目录结构:top_level/second_level/third_level/file,top_level/second_level/third_level 2/file我如何使输出与输入的目录结构匹配?现在它只是将所有输出文件放在一个目录中。2输出文件的每行前面似乎都有一个数字。它每行递增一次。几乎看起来像一个字符计数。如何确保输出中不包含数字?好的,所以我可以通过实现自己版本的TextOutputFormat类来解决第二个问题,该类排除了键的输出。但仍在试图找出如何使目录结构在输入和输出之间匹配。我认为您可以使用此处解释的MultipleTextOutputFormat来解决此问题:为此,您需要首先在映射中使用以下内容读取输入文件路径:FileSplit context.getInputSplit.getPath.getName,然后使用它相应地设置输出的键,并将完整的有效负载作为值。首先阅读上面的链接,然后你可能会更好地理解它。让我们看看这是否有帮助。
job.setNumReduceTasks(0);