大數據hadoop學習【13】-----通過JAVA編程實現對MapReduce的數據進行去重


之前的博客中,林君學長帶大家瞭解了什麼是MapReduce以及它的用途,並進行了一個簡單的例子實現對詞頻的統計;本次博客,我們將深入瞭解MapReduce,並通過java編程實現對文件數據中數據的去重,一起看步驟吧!

一、數據準備

1、ubuntu文件系統中準備對應數據文件

1)、在對應位置創建file1.txt文件,並寫入相關數據:文件中的每行都是一個數據
(1)、創建file1.txt文件,並打開

cd ~/lenovo/data
touch file1.txt
gedit file1.txt

其中 ~/lenovo/data爲林君自己創建的文件夾
(2)、寫入文件內容如下所示:

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

2)、在相同位置創建file2.txt文件,並寫入數據,兩個文件中的數據應該要有相同的和不同的,且文件中的每行都是一個數據
(1)、創建file2.txt文件,並打開

touch file2.txt
gedit file2.txt

(2)、寫入文件內容如下所示:

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

在這裏插入圖片描述

2、運行hadoop

1)、終端輸入以下命令運行hadoop

start-dfs.sh

2)、查看hadoop是否成功運行

jps

在這裏插入圖片描述
出現以上4個節點則爲成功運行!

3、將文件上傳至hadoop文件系統

1)、在hdfs文件系統中創建file1目錄用來存放我們上傳的文件

hdfs dfs -mkdir /user/hadoop/file1

2)、將file1.txt文件上傳至hdfs文件系統中的file1目錄

hdfs dfs -put ~/lenovo/data/file1.txt /user/hadoop/file1

3)、將file2.txt文件上傳至hdfs文件系統中的file1目錄

hdfs dfs -put ~/lenovo/data/file2.txt /user/hadoop/file1

4)、查看文件是否上傳成功

hdfs dfs -ls /user/hadoop/file1

在這裏插入圖片描述
5)、查看文件內容是否一致

hdfs dfs -cat /user/hadoop/file1/file1.txt
hdfs dfs -cat /user/hadoop/file1/file2.txt

在這裏插入圖片描述

二、編寫java程序

1、打開eclipse,編寫數據去重的java代碼

數據去重實例的最終目的是讓原始數據中出現次數超過一次的數據在輸出文件中只出現一次。我們自然而然會想到將同一個數據的所有記錄都交給一臺Reduce機器,無論這個數據出現多少次,只要在最終的結果中輸出一次就行了。具體就是Reduce的輸入應該以數據作爲Key,而對value-list則沒有要求。當Reduce接收到一個<key,value-list>時就直接將Key複製輸出的Key中,並將value設置成空值。

1)、新建類DataDedup ,其中java代碼如下所示:

import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
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 org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;
public class DataDedup {
	public static class Map extends Mapper<Object,Text,Text,Text>{
		private static Text line=new Text();//每行數據
		public void map(Object key,Text value,Context context) throws IOException,InterruptedException{
			line=value;
			context.write(line, new Text(""));
		}
	}
	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(""));
		}
	}
	@SuppressWarnings("deprecation")
	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: datadedup <in> <out>");
			System.exit(2);
		}
		Job job = new Job(conf, "data dedup");
		job.setJarByClass(DataDedup.class);
		job.setNumReduceTasks(1);//設置reduce輸入文件一個,方便查看結果,如設置爲0就是不執行reduce,map就輸出結果
		job.setMapperClass(Map.class);
		job.setCombinerClass(Reduce.class);
		job.setReducerClass(Reduce.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);
	}
}

在MapReduce流程中,Map的輸出<Key,value>經過shuffle過程聚集成<key,value-list>後會被交給Reduce。所以從設計好的Reduce輸入可以反推出Map的輸出的Key應爲數據,而value爲任意值。繼續反推,Map輸出的Key爲數據。而在這個實例中每個數據代表輸入文件中的一行內容,所以Map階段要完成的任務就是在採用Haodoop默認的作業輸入方式之後,將value設置成Key,並直接輸出(輸出中的value任意)。Map中的結果經過shuffle過程之後被交給reduce。在Reduce階段不管每個Key有多少個value,都直接將輸入的Key複製爲輸出的Key,並輸出就可以了(輸出中的value被設置成空)

2)、運行,測試代碼沒有問題
在這裏插入圖片描述
控制檯出現如上顯示則代碼沒有問題!

2、將java文件打包成jar

1)、按照如下截圖步驟鏡像jar打包
在這裏插入圖片描述
2)、選擇JAR file
在這裏插入圖片描述
3)、選擇導出的類和導出路徑
在這裏插入圖片描述
4)、點擊ok
在這裏插入圖片描述
5)、導出成功
在這裏插入圖片描述
出現finished則爲導出成功!
6)、找到對應路徑,查詢該包是否成功導出
在這裏插入圖片描述
出現以上jar包,則導出成功,然後關閉eclipse

三、結果測試

1、終端運行jar包

1)、終端輸入如下命令運行我們導出的jar包

hadoop jar ~/lenovo/bigData/myapp/DataDedup.jar /user/hadoop/file1 /user/hadoop/output2

提示: 路徑 /user/hadoop/output2中的output2不用我們創建,該命令會自動幫我們創建的,但我們輸入的output2是要保證hdfs中沒有與之相同的名稱哦,不然會報錯的,其中 /user/hadoop/file1是我們創建好的保存測試文件的目錄哦!
2)、出現如下界面則爲成功運行
在這裏插入圖片描述
在這裏插入圖片描述

2、查看運行結果

1)、終端輸入以下命令查看我們去重的結果

hdfs dfs -cat /user/hadoop/output2/*

2)、查看結果如下所示:
在這裏插入圖片描述

3、運行結果分析

1)、最開始的兩個文件的數據如下所示:
在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述

上面的左邊爲file1.txt,中間爲file2.txt,右邊爲最終運行的結果

2)、在上面的結果中我們可以看出,運行出來的結果將我們上面兩個文件的結果相結合,然後去除掉了重複元素,只保留了相同的其中一個
3)、除此之外,該代碼還實現了對數據的排序,因爲文件中再末尾的數據2020-4-3 c 在最終的運行結果中通過排序在上面去了哦!
4)、需要注意的是:如果要再次運行DataDedup.jar,需要首先刪除HDFS中的output2目錄,否則會報錯

4、實驗結束,關閉hadoop

stop-dfs.sh

在這裏插入圖片描述

以上就是本次博客的全部內容啦,通過對本次博客的閱讀,希望小夥伴理解如何通過java對MapReduce的數據進行操作,進而理解原理,這樣以後的編程中,就可以通過原理編程,而不是面向百度編程!
遇到問題的小夥伴記得留言評論哦,林君學長看到會爲大家解答的,這個學長不太冷!

陳一月的又一天編程歲月^ _ ^

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章