hadoop入門五步走
入門五步走
第一步 安裝hadoop叢集
- 1、安裝jdk,當前為jdk8,jdk9、10、11由於會移除一些類,導致hadoop叢集安裝失敗
安裝細節不在贅述 - 2、hadoop的安裝細節可參考下面這倆篇文章
https://blog.csdn.net/dream_an/article/details/80258283
https://www.cnblogs.com/frankdeng/p/9047698.html
注意的地方:Namenode和ResourceManger如果不是同一臺機器,不能在NameNode上啟動 yarn,應該在ResouceManager所在的機器上啟動yarn。
第二步 理解相關概念以及hadoop的模型
可以瀏覽w3c的描述,熟悉hadoop的概念
https://www.w3cschool.cn/hadoop/第三步 操作操作
*1、 直接在服務端操作使用hadoop命令做一些操作
給出一個檔案上傳到hdfs和下載到本地的example
# 1st在本地新建一個檔案 [root@node21 admin]# cat wc.txt a,1 b,1 b,5 a,3 c,3 d,15 e,11 a,2 d,2 # 2st 在hadoop上建立一個目錄,用於存放該檔案 [root@node21 admin] hadoop fs -mkdir -p/user/input 可以看到hadoop的fs命令下,有很多和linux命令相似的地方,無聊可以help看哈 root@node21 admin]# hadoop fs --help --help: Unknown command Usage: hadoop fs [generic options] [-appendToFile <localsrc> ... <dst>] [-cat [-ignoreCrc] <src> ...] [-checksum <src> ...] [-chgrp [-R] GROUP PATH...] [-chmod [-R] <MODE[,MODE]... | OCTALMODE> PATH...] [-chown [-R] [OWNER][:[GROUP]] PATH...] [-copyFromLocal [-f] [-p] [-l] [-d] [-t <thread count>] <localsrc> ... <dst>] [-copyToLocal [-f] [-p] [-ignoreCrc] [-crc] <src> ... <localdst>] [-count [-q] [-h] [-v] [-t [<storage type>]] [-u] [-x] [-e] <path> ...] [-cp [-f] [-p | -p[topax]] [-d] <src> ... <dst>] [-createSnapshot <snapshotDir> [<snapshotName>]] .................省略一堆堆 # 3st 上傳到該目錄 [root@node21 admin]hadoop fs -put ~/wc.txt/user/input # 4st 檢視是否已經存在該檔案 [root@node21 admin]# hadoop fs -ls /user/input -rw-r--r--2 admin supergroup38 2019-03-30 08:41 /user/input/wc.txt #5stok接下來下載到本地並檢視 [root@node21 admin]# hadoop fs -get /user/input/wc.txt /home/ admin/hadoop/ xzg/ [root@node21 admin]# hadoop fs -get /user/input/wc.txt /home/ [root@node21 admin]# ls /home/ wc.txt ### 就醬。
-
2、執行一個hadoop的簡單事例,瞭解map-reduce機制
先給出命令,執行該命令是注意要使用hadoop使用者,就是配置hadoop的使用者
hadoop jar /opt/hadoop3/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.1.jar wordcount /user/input/word.txt /user/output
上面hadoop jar 執行jar包,hadoop-mapreduce-examples-3.1.1.jar這個jar就是hadoop自己提供的,這裡面有很多簡單的例子(有興趣可以解壓或者官網或者到github檢視相關原始碼),wordcount 就是其中一個。這裡我們指定執行wordcount例子(用於計算單詞數量)
輸入路徑:/user/input/word.txt 是要我們自己編寫檔案上傳到hdfs的/user/input路徑下。內容可參考
[admin@node21 ~]$ hadoop fs -cat /user/input/word.txt i love you
/user/output是我們指定輸出的結果路徑
執行結果如下(part-r-00000是預設結果生產的檔案,可以hadoop fs -ls /user/outpu檢視):
[admin@node21 ~]$ hadoop fs -cat /user/output/part-r-00000 i1 love1 you 1
第四步 本地開發
我這裡使用的idea,作為本地開發工具
-
1st 首先需要匯入相關jar包,jar來源就是下載hadoop後解壓後的share檔案裡(具體以個人,不過主要common、hdfs、mapreduce、yarn這幾個包下的)
圖片.png
-
2st 將hadoop服務端的配置檔案,加入專案src目錄下。專案啟動時會使用到,否則會報錯

圖片.png
-
3st 開發前需要配置開發環境的hadoop的path
圖片.png
windows本地執行mr程式時(不提交到yarn,執行在jvm靠執行緒執行),hadoop.dll防止報nativeio異常、winutils.exe沒有的話報空指標異常。
所以我們需要額外新增這winutils.exe到你本地hadoop的bin目錄下,
(github下載地址)[ https://github.com/steveloughran/winutils] 根據服務端及本地hadoop版本選擇,不過我使用3.1的選擇的3.0版本
- 4st 一個簡單的測試連線服務端hdfs類
public class Chapter3 { public static void main(String[] args) { try { String filename = "hdfs://10.11.91.225:9000/user/input/data.txt"; Configuration conf = new Configuration(); conf.set("fs.defaultFS", "hdfs://10.11.91.225:9000"); //conf.set("mapreduce.jobtracker.address", "10.11.91.255:9000"); // 這個解決hdfs問題 conf.set("fs.hdfs.impl", org.apache.hadoop.hdfs.DistributedFileSystem.class.getName()); // 這個解決本地file問題 conf.set("fs.file.impl", org.apache.hadoop.fs.LocalFileSystem.class.getName()); FileSystem fs = FileSystem.get(conf); if(fs.exists(new Path(filename))) { System.out.println("檔案存在"); //fs. }else{ System.out.println("檔案不存在"); } } catch (Exception e) { e.printStackTrace(); } } }
上面程式碼本地開發環境和遠端服務的連通測試
-
3st 編寫一個任務,從本地開發環境丟到hadoop叢集上執行(這是一個計算單詞key,合併value的例子)
先寫個檔案丟到hdfs上
[admin@node21 ~]$ hadoop fs -cat /user/input/wc.txt a,1 b,1 b,5 a,3 c,3 d,15 e,11 a,2 d,2
預期我們想要的結果如下:
a6 b6 c3 d17 e11
程式碼實現,主要三個類
- WordCountMapper 類用於split和map階段
// //這個Mapper類是一個泛型型別,它有四個形參型別,分別指定map函式的輸入鍵、輸入值、輸出鍵、輸出值的型別 public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> { //該方法迴圈呼叫,從檔案的split中讀取每行呼叫一次,把該行所在的下標為key,該行的內容為value protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { String[] words = StringUtils.split(value.toString(), ' '); for(String w :words){ //a,1 a,2 重新組裝a:1 a:2 String[] kevs = w.split(","); context.write(new Text(kevs[0]), new IntWritable(Integer.valueOf(kevs[1]))); } } }
- WordCountReducer類用於Shuffle和reduce階段
public class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable> { //每組呼叫一次,這一組資料特點:key相同,value可能有多個。 protected void reduce(Text arg0, Iterable<IntWritable> arg1, Context arg2) throws IOException, InterruptedException { //增加所有的值 int sum =0; for(IntWritable i: arg1){ sum=sum+i.get(); } arg2.write(arg0, new IntWritable(sum)); } }
- RunJob類為程式的入口和job的設定
public class RunJob { public static void main(String[] args) { Configuration config =new Configuration(); //config.set("fs.defaultFS", "hdfs://HadoopMaster:9000"); config.set("fs.defaultFS", "hdfs://10.11.91.225:9000"); //node22為hadoopyarn-site.xml中的配置 config.set("yarn.resourcemanager.hostname", "node22"); //設定執行的使用者,需要是服務端的hadoop使用者,否則無許可權執行,報錯.AccessControlException: Permission denied System.setProperty("HADOOP_USER_NAME", "admin"); //config.set("mapred.jar", "C:\\Users\\Administrator\\Desktop\\wc.jar");//先打包好wc.jar try { FileSystem fs =FileSystem.get(config); Job job = Job.getInstance(config); job.setJarByClass(RunJob.class); job.setJobName("wc"); job.setMapperClass(WordCountMapper.class); job.setReducerClass(WordCountReducer.class); job.setMapOutputKeyClass(Text.class); job.setMapOutputValueClass(IntWritable.class); FileInputFormat.addInputPath(job, new Path("/user/input/wc.txt"));//新建好輸入路徑,且資料來源 Path outpath =new Path("/user/output/wc"); if(fs.exists(outpath)){ fs.delete(outpath, true); } FileOutputFormat.setOutputPath(job, outpath); boolean f= job.waitForCompletion(true); if(f){ System.out.println("job任務執行成功"); } } catch (Exception e) { e.printStackTrace(); } } }
注意:由於本地為windows下環境需要修改hadoop原始碼,否則會出現NativeIO$Windows.access錯誤
(hadoop原始碼)[ https://github.com/apache/hadoop] 下載本地後修改如下檔案
\hadoop-common-project\hadoop-common\src\main\java\org\apache\hadoop\io\nativeio\NativeIO.java

圖片.png
修改後新增到本地,新建的包名要和hadoop的相同,這樣本地執行引入的jar會優先載入該類。

圖片.png
最後執行成功後,檢視執行結果
[admin@node21 ~]$ hadoop fs -cat /user/output/wc/part-r-00000 a6 b6 c3 d17 e11
和預期相同,很好
最後順便貼出專案結構吧

圖片.png
第五步
剩下的理解上面的程式碼,然後根據自己想法編寫,已經理解hadoop執行原理和原始碼。好了,你已經算是入門了,哦 錯了 應該是我
什麼 原始碼? 那就上傳到 gayhub