MapReduce经典案例—数据去重

本文详细介绍了如何使用Hadoop MapReduce技术对file1.txt和file2.txt中的重复数据进行去重,通过自定义Mapper和Reducer实现,并展示了完整的代码和运行结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、问题介绍

(一)案例分析

1. 数据去重介绍

2. 案例需求及分析

(二)案例实现

1. Map阶段实现

2. Reduce阶段实现

3.  Driver程序主类实现

4.  效果测试

二、完整代码

file1.txt

file2.txt

1、DedupMapper.Java 

2、DedupReducer.java

3、DedupDriver.java 

三、运行结果 


一、问题介绍

(一)案例分析

1. 数据去重介绍

数据去重主要是为了掌握利用并行化思想来对数据进行有意义的筛选,数据去重指去除重复数据的操作。在大数据开发中,统计大数据集上的多种数据指标,这些复杂的任务数据都会涉及数据去重。

2. 案例需求及分析

文件file1.txt本身包含重复数据,并且与file2.txt同样出现重复数据,现要求使用Hadoop大数据相关技术对以上两个文件进行去重操作,并最终将结果汇总到一个文件中。 (1) 编写MapReduce程序,在Map阶段采用Hadoop默认作业输入方式后,将key设置为需要去重的数据,而输出的value可以任意设置为空。 (2) 在Reduce阶段,不需要考虑每一个key有多少个value,可以直接将输入的key复制为输出的key,而输出的value可以任意设置为空,这样就会使用MapReduce默认机制对key(也就是文件中的每行内容)自动去重

(二)案例实现

1. Map阶段实现

使用Eclipse开发工具打开之前创建的Maven项目HadoopDemo,并且新创建cn.itcast.mr.dedup包,在该路径下编写自定义Mapper类DedupMapper,主要用于读取数据集文件将TextInputFormat默认组件解析的类似<0,2018-3-1 a >键值对修改为<2018-3-1 a,null>。

2. Reduce阶段实现

根据Map阶段的输出结果形式,同样在cn.itcast.mr.dedup包下,自定义Reducer类DedupReducer,主要用于接受Map阶段传递来的数据,根据Shuffle工作原理,键值key相同的数据就会被合并,因此输出数据就不会出现重复数据了。

3.  Driver程序主类实现

编写MapReduce程序运行主类DedupDriver,主要用于设置MapReduce工作任务的相关参数。由于本次演示的数据量较小,为了方便、快速地进行案例演示,本案例采用了本地运行模式,对指定的本地D:\\Dedup\\input目录下的源文件(需要提前准备)实现数据去重,并将结果输入到本地D:\\Dedup\\output目录下。

4.  效果测试

为了保证MapReduce程序正常执行,需要先在本地D:\\Dedup\\input目录下创建文件file1.txt和file2.txt;然后,执行MapReduce程序的程序入口DedupDriver类,正常执行完成后,在指定的D:\\Dedup\\output目录下生成结果文件。

二、完整代码

file1.txt

2019-3-1 a
2019-3-2 b
2019-3-3 c
2019-3-4 d
2019-3-5 a
2019-3-6 b
2019-3-7 c
2019-3-3 c

file2.txt

2019-3-1 b
2019-3-2 a
2019-3-3 b
2019-3-4 d
2019-3-5 a
2019-3-6 c
2019-3-7 d
2019-3-3 c

1、DedupMapper.Java 

package cn.itcast.mr.dedup;

import java.io.IOException;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

public class DedupMapper extends Mapper<LongWritable, Text, Text, NullWritable> {
	private static Text line = new Text();//每行数据
	@Override
	protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, NullWritable>.Context context)throws IOException, InterruptedException {
		line = value;
		context.write(line,NullWritable.get());	
	}

	
}

2、DedupReducer.java

package cn.itcast.mr.dedup;

import java.io.IOException;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

public class DedupReducer extends Reducer<Text, NullWritable, Text, NullWritable> {
    //重写reduce()方法
    @Override
    protected void reduce(Text key, Iterable<NullWritable> values, Reducer<Text, NullWritable, Text, NullWritable>.Context context) throws IOException, InterruptedException {
        context.write(key,NullWritable.get());
    }
}

3、DedupDriver.java 

package cn.itcast.mr.dedup;

import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.Job;

public class DedupDriver {
	 public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
	      

	        Configuration conf = new Configuration();
	        Job job = Job.getInstance(conf);
	        
	        job.setJarByClass(DedupDriver.class);
	        job.setMapperClass(DedupMapper.class);
	        job.setReducerClass(DedupReducer.class);
	        //设置输出类型
	        job.setOutputKeyClass(Text.class);
	        job.setOutputValueClass(NullWritable.class);
	        //设置输入和输出目录
	        FileInputFormat.addInputPath(job, new Path("F:\\Dedup\\input"));
	        FileOutputFormat.setOutputPath(job, new Path("F:\\Dedup\\output"));
	 
	        System.exit(job.waitForCompletion(true) ? 0 : 1);
	    }

}

三、运行结果 

Hadoop MapReduce中,处理数据并统计每个元素出现次数通常涉及两个阶段:Map阶段和Reduce阶段。这里是一个简单的伪代码示例: ```java // Mapper阶段 Mapper<Long, Text, Key, Value> map = new Mapper() { public void map(Long key, Text value, Context context) throws IOException, InterruptedException { String line = value.toString(); // 对输入行进行解析,例如分割键值对 String[] fields = line.split(","); if (fields.length > 1) { // 验证是否有两部分,假设第一部分是唯一标识 String element = fields[0]; context.write(element, new IntWritable(1)); // 发送元素和计数到Reduce } } }; // Reducer阶段 Reducer<Key, Iterable<Value>, Key, IntWritable> reduce = new Reducer<Key, Value, Key, IntWritable>() { public void reduce(Key key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { int sum = 0; for (IntWritable val : values) { sum += val.get(); //累加每个元素出现的次数 } context.write(key, new IntWritable(sum)); // 输出后的元素及其出现次数 } }; Job job = Job.getInstance(conf, "word count"); job.setMapperClass(map); job.setReducerClass(reduce); job.setOutputKeyClass(String.class); job.setOutputValueClass(IntWritable.class); job.setInputFormatClass(TextInputFormat.class); job.setOutputFormatClass(TextOutputFormat.class); ``` 在这个例子中,`Mapper`负责读取每一行数据,检查是否需要,然后发送元素及其计数到`Reducer`。`Reducer`接收到所有相同的元素计数后,将它们相加得到最终的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值