实例描述:

现有两个文件,dedu1.txt和dedu2.txt,数据文件中的每一行都是一个数据,现要对这两个文件进行去重,两个文件内容分别为(同颜色的表示重复的数据):



        dedu1.txt:                                            dedu2.txt:

           2012-3-1 a                                                2012-3-1 b

           2012-3-2 b                                                2012-3-2 a

           2012-3-3 c                                                2012-3-3 b

           2012-3-4 d                                                2012-3-4 d

           2012-3-5 a                                                2012-3-5 a

           2012-3-6 b                                                2012-3-6 c

           2012-3-7 c                                                2012-3-7 d

           2012-3-3 c                                                2012-3-3 c


考查重点及设计思路:

考查重点:MapReduce会把相同key值的<key,value>对发送至同一台reduce机器上进行处理,无论这个key值出现多少次,只要在最终结果输出一次就可以了。所以这里应该把每行数据作为可以key值,value值没有要求,可以设置为空。

设计思路

按照默认的TextInputFormat格式每行文本形成一个<key,vlaue>对,key为行号,value为文本值;

在Mapper中进行处理时,将key设置为文本值(即Map输入的value值),value设置为空即可,因为此处不需要知道key值得个数等其他信息,所以此时只要比较key是否相等就可判断是否为重复的数据;

在Reducer中进行处理时,因为所有相同key值得value对都会送至一台reduce机器上调用reduce函数进行处理。在reduce函数中,我们知道reduce函数的输入是一个key值和这个key相对应的一个value列表,所以我们这里我们不管这个key值有多少个value,只要直接将key复制为输出的key值简单的输出一次即可(输出的value设置为空)。


程序代码如下:

Mapper类:

public class DeDuMap extends Mapper<Object, Text, Text, Text>{
	private Text data = new Text();
	public void map(Object key, Text value,Context context)
		throws IOException, InterruptedException{
		data.set(value.toString());
		context.write(data, new Text(""));
	}
}

Reducer类:

public class DeDuReduce extends Reducer<Text, Text, Text, Text>{
	public void reduce(Text key, Iterable<Text> values, Context context)
		throws IOException, InterruptedException{
		context.write(key, new Text(""));
	}
}

主函数:

public class DeDumain {
	public static void main(String[] args) throws Exception{
		Configuration conf = new Configuration();
		
		String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
	    if (otherArgs.length != 2) {
	      System.err.println("Usage: Dedumain <in> <out>");
	      System.exit(2);
	    }
	    
	    Job job = new Job(conf,"de du");
	    job.setJarByClass(DeDumain.class);
	    
	    job.setMapperClass(DeDuMap.class);
	    job.setCombinerClass(DeDuReduce.class);
	    job.setReducerClass(DeDuReduce.class);
	   
	    job.setOutputKeyClass(Text.class);
	    job.setOutputValueClass(Text.class);
	    
	    FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
	    FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));
	    
	    System.exit(job.waitForCompletion(true)? 0:1);
	}
}