1.1 Hadoop環境配置java
本文用於指導hadoop在windows10環境下單機版的使用,軟件版本選擇:node
l Windows10家庭版web
l JDK 1.8.0_171-b11算法
l hadoop-2.7.3apache
1.1.1 Hadoop簡要介紹編程
Hadoop 是Apache基金會下一個開源的分佈式計算平臺,它以分佈式文件系統HDFS和MapReduce算法爲核心,爲用戶提供了系統底層細節透明的分佈式基礎架構。windows
從官網下載Hadoop二進制版本,而後解壓到:D:\Study\codeproject\hadoop-2.7.3。服務器
Java是Hadoop依賴的運行環境,讀者能夠在Oracle官網獲取最新版的Java版本,因爲只是運行不是開發,因此也能夠只下載JRE。安裝完成後配置安裝完成後,配置JAVA_HOME和JRE_HOME環境變量。執行以下命令表示JDK安裝成功:網絡
C:\Users\45014>java -versionsession
java version "1.8.0_171"
Java(TM) SE Runtime Environment (build 1.8.0_171-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)
右鍵單擊個人電腦 –>屬性 –>高級環境變量配置 –>高級選項卡 –>環境變量 –> 單擊新建HADOOP_HOME,接着編輯環境變量path,將hadoop的bin目錄加入到後面
l 編輯「D:\Study\codeproject\hadoop-2.7.3\etc\hadoop」下的core-site.xml文件:
<configuration>
<property>
<name>hadoop.tmp.dir</name>
<value>/D:/Study/codeproject/hadoop-2.7.3/data/temp</value>
</property>
<property>
<name>dfs.name.dir</name>
<value>/D:/Study/codeproject/hadoop-2.7.3/data/name</value>
</property>
<property>
<name>fs.default.name</name>
<value>hdfs://localhost:9000</value>
</property>
<property>
<name>fs.defaultFS</name>
<value>hdfs://localhost:9000</value>
</property>
</configuration>
l 編輯「D:\Study\codeproject\hadoop-2.7.3\etc\hadoop」下的mapred-site.xml文件:
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>mapred.job.tracker</name>
<value>hdfs://localhost:9001</value>
</property>
</configuration>
l 編輯「D:\Study\codeproject\hadoop-2.7.3\etc\hadoop」下的hdfs-site.xml文件:
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value> <!-- 這個參數設置爲1,由於是單機版hadoop -->
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>/D:/Study/codeproject/hadoop-2.7.3/data/namenode</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>/D:/Study/codeproject/hadoop-2.7.3/datanode</value>
</property>
<property>
<name>dfs.data.dir</name>
<value>/D:/Study/codeproject/hadoop-2.7.3/datanode</value>
</property>
</configuration>
l 編輯「D:\Study\codeproject\hadoop-2.7.3\etc\hadoop」下的yarn-site.xml文件:
<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
<value>org.apache.hadoop.mapred.ShuffleHandler</value>
</property>
</configuration>
(1)進入D:\Study\codeproject\hadoop-2.7.3\bin目錄,格式化hdfs,在cmd中運行命令 hdfs namenode -format
(2)運行cmd窗口,切換到hadoop的sbin目錄,執行「start-all.cmd」,它將會啓動如下進程。
啓動成功後,進入資源管理GUI:http://localhost:8088/
節點管理GUI:http://localhost:50070/;
1.在eclipse上安裝Hadoop插件
把下載好的hadoop-eclipse-plugin-2.7.1.jar文件拷貝到eclipse安裝目錄中的plugins文件夾內(注意版本選擇,不然可能致使不可用)。以下圖:
2.繼續配置hadoop編譯環境(方便配置,確保已經啓動了 Hadoop)
啓動 Eclipse 後就能夠在左側的Project Explorer中看到DFS Locations。
3.插件的配置
第一步:選擇 Window 菜單下的 Preference。
此時會彈出一個窗體,點擊選擇 Hadoop Map/Reduce 選項,選擇 Hadoop 的安裝目錄(例如:/home/hadoop/hadoop)。
第二步:切換 Map/Reduce 開發視圖
選擇Window 菜單下選擇 Open Perspective -> Other,彈出一個窗體,從中選擇Map/Reduce 選項便可進行切換。
第三步:創建與 Hadoop 集羣的鏈接
點擊Eclipse軟件右下角的Map/Reduce Locations 面板,在面板中單擊右鍵,選擇New Hadoop Location。
在彈出來的General選項面板中,General的設置要與 Hadoop 的配置一致。通常兩個 Host值是同樣的,若是是僞分佈式,填寫 localhost 便可,這裏使用的是Hadoop僞分佈,設置fs.defaultFS爲 hdfs://localhost:9000,則 DFS Master 的 Port 改成 9000。Map/Reduce(V2) Master 的 Port 用默認的便可,Location Name 隨意填寫。
HDFS是Hadoop體系中數據存儲管理的基礎。 HDFS採用主從(Master/Slave)結構模型,一個HDFS集羣是由一個NameNode和若干個DataNode組成的。NameNode做爲主服務器,管理文件系統命名空間和客戶端對文件的訪問操做。DataNode管理存儲的數據。
1.運行cmd窗口,執行「hdfs namenode -format」;
根據你core-site.xml的配置,接下來你就能夠經過:hdfs://localhost:9000來對hdfs進行操做了。
1.建立輸入目錄
C:\Users\45014>hadoop fs -mkdir hdfs://localhost:9000/user/
C:\Users\45014>hadoop fs -mkdir hdfs://localhost:9000/user/wcinput
2.上傳數據到目錄
C:\Users\45014>hadoop fs -put D:\file1.txt hdfs://localhost:9000/user/wcinput
C:\Users\45014>hadoop fs -put D:\file2.txt hdfs://localhost:9000/user/wcinput
3.查看文件
C:\Users\45014>hadoop fs -ls hdfs://localhost:9000/user/wcinput
Found 2 items
-rw-r--r-- 1 45014 supergroup 52 2019-03-08 22:48 hdfs://localhost:9000/user/wcinput/file1.txt
-rw-r--r-- 1 45014 supergroup 13 2019-03-08 22:48 hdfs://localhost:9000/user/wcinput/file2.txt
在esclipse界面的DFS Locations右鍵點擊refresh,以下圖:
MapReduce是Google的一項重要技術,它是一個編程模型,用以進行大數據量的計算。對於大數據量的計算,一般採用的處理手法就是並行計算。至少現階段而言,對許多開發人員來講,並行計算仍是一個比較遙遠的東西。MapReduce就是一種簡化並行計算的編程模型,它讓那些沒有多少並行計算經驗的開發人員也能夠開發並行應用。
下面代碼來自網絡,一塊兒參考學習。
import java.io.IOException; import java.util.StringTokenizer; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IntWritable; 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.input.TextInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat; @SuppressWarnings("unused") public class WordCount { public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> // 爲何這裏k1要用Object、Text、IntWritable等,而不是java的string啊、int啊類型, //固然,你能夠用其餘的,這樣用的好處是,由於它裏面實現了序列化和反序列化。 // 可讓在節點間傳輸和通訊效率更高。這就爲何hadoop自己的機制類型的誕生。 // 這個Mapper類是一個泛型類型,它有四個形參類型,分別指定map函數的輸入鍵、輸入值、輸出鍵、輸出值的類型。 //hadoop沒有直接使用Java內嵌的類型,而是本身開發了一套能夠優化網絡序列化傳輸的基本類型。 // 這些類型都在org.apache.hadoop.io包中。 // 好比這個例子中的Object類型,適用於字段須要使用多種類型的時候,Text類型至關於Java中的String類型, //IntWritable類型至關於Java中的Integer類型 { // 定義兩個變量或者說是定義兩個對象,叫法均可以 private final static IntWritable one = new IntWritable(1);// 這個1表示每一個單詞出現一次,map的輸出value就是1. // 由於,v1是單詞出現次數,直接對one賦值爲1 private Text word = new Text(); public void map(Object key, Text value, Context context) // context它是mapper的一個內部類,簡單的說頂級接口是爲了在map或是reduce任務中跟蹤task的狀態,很天然的MapContext就是記錄了map執行的上下文,在mapper類中,這個context能夠存儲一些job // conf的信息,好比job運行時參數等, // 咱們能夠在map函數中處理這個信息,這也是Hadoop中參數傳遞中一個很經典的例子,同時context做爲了map和reduce執行中各個函數的一個橋樑,這個設計和Java // web中的session對象、application對象很類似 // 簡單的說context對象保存了做業運行的上下文信息,好比:做業配置信息、InputSplit信息、任務ID等 // 咱們這裏最直觀的就是主要用到context的write方法。 // 說白了,context起到的是鏈接map和reduce的橋樑。起到上下文的做用! throws IOException, InterruptedException { // The tokenizer uses the default delimiter set, which is " \t\n\r": the space // character, the tab character, the newline character, the carriage-return // character StringTokenizer itr = new StringTokenizer(value.toString());// 將Text類型的value轉化成字符串類型 while (itr.hasMoreTokens()) { // 實際上就是java.util.StringTokenizer.hasMoreTokens() // hasMoreTokens() 方法是用來測試是否有此標記生成器的字符串可用更多的標記。 word.set(itr.nextToken()); context.write(word, one); } } } public static class IntSumReducer extends Reducer<Text, IntWritable, Text, IntWritable> { private IntWritable result = new IntWritable(); public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { // 咱們這裏最直觀的就是主要用到context的write方法。 // 說白了,context起到的是鏈接map和reduce的橋樑。起到上下文的做用! int sum = 0; for (IntWritable val : values) {// 叫作加強的for循環,也叫for星型循環 sum += val.get(); } result.set(sum); context.write(key, result); } } public static void main(String[] args) throws Exception { Configuration conf = new Configuration();// 程序裏,只需寫這麼一句話,就會加載到hadoop的配置文件了 // Configuration類表明做業的配置,該類會加載mapred-site.xml、hdfs-site.xml、core-site.xml等配置文件。 // 刪除已經存在的輸出目錄 Path mypath = new Path("hdfs://localhost:9000/user/wcoutput");// 輸出路徑 FileSystem hdfs = mypath.getFileSystem(conf);// 程序裏,只需寫這麼一句話,就能夠獲取到文件系統了。 // 若是文件系統中存在這個輸出路徑,則刪除掉,保證輸出目錄不能提早存在。 if (hdfs.isDirectory(mypath)) { hdfs.delete(mypath, true); } // job對象指定了做業執行規範,能夠用它來控制整個做業的運行。 Job job = Job.getInstance();// new Job(conf, "word count"); job.setJarByClass(WordCount.class);// 咱們在hadoop集羣上運行做業的時候,要把代碼打包成一個jar文件,而後把這個文件 // 傳到集羣上,而後經過命令來執行這個做業,可是命令中沒必要指定JAR文件的名稱,在這條命令中經過job對象的setJarByClass()中傳遞一個主類就行, //hadoop會經過這個主類來查找包含它的JAR文件。 job.setMapperClass(TokenizerMapper.class); // job.setReducerClass(IntSumReducer.class); job.setCombinerClass(IntSumReducer.class);// Combiner最終不能影響reduce輸出的結果 job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); // 通常狀況下mapper和reducer的輸出的數據類型是同樣的,因此咱們用上面兩條命令就行,若是不同,咱們就能夠用下面兩條命令單獨指定mapper的輸出key、value的數據類型 // job.setMapOutputKeyClass(Text.class); // job.setMapOutputValueClass(IntWritable.class); // hadoop默認的是TextInputFormat和TextOutputFormat,因此說咱們這裏能夠不用配置。 // job.setInputFormatClass(TextInputFormat.class); // job.setOutputFormatClass(TextOutputFormat.class); FileInputFormat.addInputPath(job, new Path("hdfs://localhost:9000/user/wcinput/file1.txt"));// FileInputFormat.addInputPath()指定的這個路徑能夠是單個文件、一個目錄或符合特定文件模式的一系列文件。 // 從方法名稱能夠看出,能夠經過屢次調用這個方法來實現多路徑的輸入。 FileOutputFormat.setOutputPath(job, new Path("hdfs://localhost:9000/user/wcoutput"));// 只能有一個輸出路徑,該路徑指定的就是reduce函數輸出文件的寫入目錄。 // 特別注意:輸出目錄不能提早存在,不然hadoop會報錯並拒絕執行做業,這樣作的目的是防止數據丟失,由於長時間運行的做業若是結果被意外覆蓋掉,那確定不是咱們想要的 System.exit(job.waitForCompletion(true) ? 0 : 1); // 使用job.waitForCompletion()提交做業並等待執行完成,該方法返回一個boolean值,表示執行成功或者失敗,這個布爾值被轉換成程序退出代碼0或1,該布爾參數仍是一個詳細標識,因此做業會把進度寫到控制檯。 // waitForCompletion()提交做業後,每秒會輪詢做業的進度,若是發現和上次報告後有改變,就把進度報告到控制檯,做業完成後,若是成功就顯示做業計數器,若是失敗則把致使做業失敗的錯誤輸出到控制檯 } }