在大量数据中,难免存在重复数据,本例使用MapReduce对数据进行去重处理,使相同的数据在最终的输出结果中只保留一份。统计数据的种类个数、网站访问的IP数量等都会涉及数据去重操作。
已知有两个文件file1.txt和file2.txt,需要对这两个文件中的数据进行合并去重,文件中的每行是一个整体。
file1.txt的内容如下:
2022-3-1 a 2022-3-2 b 2022-3-3 c 2022-3-4 d 2022-3-5 a 2022-3-6 b 2022-3-7 c 2022-3-3 c
file2.txt的内容如下:
2022-3-1 b 2022-3-2 a 2022-3-3 b 2022-3-4 d 2022-3-5 a 2022-3-6 c 2022-3-7 d 2022-3-3 c
期望的输出结果如下:
2022-3-1 a 2022-3-1 b 2022-3-2 a 2022-3-2 b 2022-3-3 b 2022-3-3 c 2022-3-4 d 2022-3-5 a 2022-3-6 b 2022-3-6 c 2022-3-7 c 2022-3-7 d
根据MapReduce的工作原理可知,MapReduce的Shuffle阶段会将Map任务的结果数据进行分区,并按照key进行分组,同一组的数据将输入到同一个Reduce任务中进行处理。而根据key分组的过程,实际上就是去重。因此,将输入的每一行数据作为key即可达到数据去重的目的。
在Eclipse中新建一个Maven项目,在项目的pom.xml文件中加入Hadoop的依赖库,内容如下:
<dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-client</artifactId> <version>3.3.1</version> </dependency>
然后在Maven项目中新建数据去重类Dedup.java,完整代码如下:
上述程序中,map()方法将接收到的<key,value>对中的value直接作为方法输出的key,而方法输出的value则被置为空字符串;reduce()方法将接收到的<key,value>对中的key直接作为方法输出的key,而输出的value则被置为空字符串。
该程序需要在Hadoop集群环境下运行,步骤如下:
01 在Eclipse中将完成的MapReduce项目导出为jar包,命名为Dedup.jar,然后上传到Hadoop服务器的相应位置。
02 在HDFS根目录下创建input文件夹,命令如下:
$ hadoop fs –mkdir /input
03 将准备好的示例文件file1.txt和file2.txt上传到HDFS中的/input目录,命令如下:
$ hadoop fs –put file1.txt /input $ hadoop fs –put file2.txt /input
04 执行以下命令,运行写好的MapReduce数据去重程序:
$ hadoop jar Dedup.jar com.hadoop.mr.Dedup
上述命令中的com.hadoop.mr为程序所在的包名,Dedup为程序类名。
05 程序运行完毕后,会在HDFS的根目录下生成output目录,并在output目录中生成part-r-00000文件,程序执行结果即存放于该文件中。可以执行以下命令,查看程序执行结果:
$ hadoop fs –cat /output/*
如果能正确显示预期结果,则表明程序编写无误。