第七章 mapreduce编程实践-文件合并与去重

编程实现文件合并和去重操作

对于两个输入文件,即文件A和文件B,请编写MapReduce程序,对两个文件进行合并,并剔除其中重复的内容,得到一个新的输出文件C。下面是输入文件和输出文件的一个样例供参考。

目标:原始数据中出现次数超过一次的数据在输出文件中只出现一次。

算法思想:根据reduce的过程特性,会自动根据key来计算输入的value集合,把数据作为key输出给reduce,无论这个数据出现多少次,reduce最终结果中key只能输出一次。

 

1.实例中每个数据代表输入文件中的一行内容,map阶段采用Hadoop默认的作业输入方式。将value设置为key,并直接输出。 map输出数据的key为数据,将value设置成空值
2.在MapReduce流程中,map的输出<key,value>经过shuffle过程聚集成<key,value-list>后会交给reduce
3.reduce阶段不管每个key有多少个value,它直接将输入的key复制为输出的key,并输出(输出中的value被设置成空)。

 

 

用一行作为key,value是空,那么在reduce时进行“汇总”,还是只有一个key,即一行,value还是空。所以即去重了。

    输入文件A的样例如下:

        20150101     x

        20150102     y

        20150103     x

        20150104     y

        20150105     z

        20150106     x

输入文件B的样例如下:

20150101      y

20150102      y

20150103      x

20150104      z

20150105      y

根据输入文件A和B合并得到的输出文件C的样例如下:

20150101      x

20150101      y

20150102      y

20150103      x

20150104      y

20150104      z

20150105      y

 2015010      z

20150106      x

 

代码:

package org.apache.hadoop.examples;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import java.io.IOException;
import java.util.StringTokenizer;

public class FileMerge {
 
 public static void main(String[] args) throws Exception {
       Configuration conf = new Configuration();//获得程序参数 放到otherArgs中
     //   String[] otherArgs = (new GenericOptionsParser(conf, args)).getRemainingArgs();
        String[] otherArgs=new String[]{"input","output"}; /* 直接设置输入参数 设置程序运行参数 */
        if(otherArgs.length < 2) {//没有指定参数
            System.err.println("Usage: FileMerge <in> [<in>...] <out>");
            System.exit(2);
        }
 
        Job job = Job.getInstance(conf, "FileMerge");//设置环境参数
        job.setJarByClass(FileMerge.class);//设置整个程序的类名
        job.setMapperClass(FileMerge.Map.class);//添加Mapper类
        job.setCombinerClass(FileMerge.Reduce.class);//添加combiner类
        job.setReducerClass(FileMerge.Reduce.class);//添加reducer类
        job.setOutputKeyClass(Text.class);//设置输出类型
        job.setOutputValueClass(Text.class);//设置输出类型
		//System.exit(job.waitForCompletion(true) ? 0 : 1);
        for(int i = 0; i < otherArgs.length - 1; ++i) { 
            FileInputFormat.addInputPath(job, new Path(otherArgs[i]));//设置输入文件
        }
 
        FileOutputFormat.setOutputPath(job, new Path(otherArgs[otherArgs.length - 1]));//设置输出文件
		Path path = new Path(otherArgs[1]);// 取第1个表示输出目录参数(第0个参数是输入目录)
		FileSystem fileSystem = path.getFileSystem(conf);// 根据path找到这个文件
		if (fileSystem.exists(path)) {//如果存在output文件夹则删除
			fileSystem.delete(path, true);// true的意思是,就算output有东西,也一带删除
	System.exit(job.waitForCompletion(true)?0:1);
			}
    }
    
        //实现map函数
 
        public static class Map  extends Mapper<Object, Text, Text, Text> {//继承mapper父类  //接收一个文件名作为key,该文件的每行内容作为value
        
			private Text line = new Text();//每一行作为一个数据 
			 public Map() {
		        }
			public void map(Object key, Text value, Mapper<Object, Text, Text, Text>.Context context) throws IOException, InterruptedException {
		   
						 context.write(value, new Text(""));//把每一行都放到text中 唯一的key实现了去重
            }
		}
 // reduce将输入中的key复制到输出数据的key上,并直接输出,这是数据去重思想
    public static class Reduce extends Reducer<Text, Text, Text, Text> {
        public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
          context.write(key, new Text("")); //map传给reduce的数据已经做完数据去重,输出即可
        }
    }
 
 
    
}

 

  • 14
    点赞
  • 117
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: MapReduce编程可以实现文件合并去重操作。具体步骤如下: 1. 首先,将需要合并去重文件上传到Hadoop分布式文件系统(HDFS)中。 2. 接着,编写MapReduce程序,其中Mapper阶段的任务是将输入文件中的每一行作为key,value为空的键值对输出。Reducer阶段的任务是将相同的key合并,并去除重复的value。 3. 在MapReduce程序中,需要设置输入路径和输出路径。输入路径为需要合并去重文件所在的HDFS目录,输出路径为合并去重后的文件所在的HDFS目录。 4. 运行MapReduce程序,等待程序执行完毕。 5. 最后,从输出路径中获取合并去重后的文件,即可完成文件合并去重操作。 需要注意的是,在MapReduce程序中,需要设置合适的Reducer数量,以保证程序的性能和效率。同时,还需要考虑到数据倾斜等问题,采取相应的优化措施,以提高程序的运行效率。 ### 回答2: MapReduce是一种在数据处理领域广泛使用的编程模型。本文将讨论如何使用MapReduce实现文件合并去重操作。 文件合并: 假设有多个文件需要合并成一个文件。我们可以将每个文件映射到一个键值对中,其中键表示文件名,值表示文件内容。然后通过Reduce函数将所有值合并到一个文件中。 具体实现步骤如下: 1. 将每个文件映射到一个键值对中。键为文件名,值为文件内容。 2. 将所有键值对按照键进行排序。 3. 在Reduce函数中,将所有值合并到一个文件中。 具体代码如下: map(key, value): # 将每个文件映射到一个键值对中 emit(key, value) reduce(key, values): # 将所有值合并到一个文件中 with open(key, "wb") as outfile: for value in values: outfile.write(value) 文件去重: 假设有多个文件中的记录存在重复数据,需要将其去重。我们可以将每个记录映射到一个键值对中,其中键表示记录的内容,值为1。然后通过Reduce函数将所有值合并到一个文件中,去除重复数据。 具体实现步骤如下: 1. 将每个记录映射到一个键值对中。键为记录的内容,值为1。 2. 在Reduce函数中,将所有值累加起来,去除值大于1的记录。 具体代码如下: map(key, value): # 将每个记录映射到键值对中 emit(key, 1) reduce(key, values): # 去除重复记录 count = 0 for value in values: count += value if count == 1: emit(key, "") ### 回答3: MapReduce编程模型是处理大规模数据集的强大工具,可以帮助我们快速地完成文件合并去重操作。文件合并去重操作是企业中日常工作中非常常见的操作,特别是对于需要处理海量数据的企业而言,这些操作尤为重要。 文件合并操作: MapReduce编程模型的文件合并操作可以分为两个步骤——map和reduce。 1. Map操作: Map操作的核心是将文件中的每一行都作为一个key-value对,将每个key相同的value按顺序组合成一组,作为reduce操作的输入。对于大规模的数据集,我们可以将数据分为多个不同的部分,每部分都运行一个独立的mapper,将处理结果输出到文件系统上。 2. Reduce操作: Reduce操作的主要目的是将经过Map操作后产生的key-value对按照某种规则聚合在一起,用于生成最终的输出文件。对于需要进行文件合并的场景,最终输出的文件是由多个经过合并后的小文件组成。 去重操作: 去重操作与文件合并类似,也可以使用MapReduce编程模型,需要分为两个步骤——map和reduce。 1. Map操作: Map操作的核心是将重复的数据进行分组。对于map操作,我们可以将数据集中所有的value都设为一个常数,这样检测重复值只需要比较key即可。在map操作中,如果发现有相同的key-value对,就将其过滤掉,只传递其中一个给reduce操作。 2. Reduce操作: Reduce操作的主要功能是将来自不同mapper的处理结果聚合起来,生成最终的输出结果。在去重操作中,reduce操作会输出所有的不重复的数据。 总而言之,MapReduce编程模型可以帮助我们快速地完成文件合并去重操作,扩大了我们处理大规模数据集的能力,也有助于加快企业的数据处理效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值