第1章 引言
1.1 編寫目的
對關於hadoop的文檔及資料進行進一步的整理。
1.2 相關網站
毋庸置疑 http://hadoop.apache.org/
國內 http://www.hadoopor.com/ 專門研究hadoop的,《hadoop開發者》由該站創辦,已發4期
中國雲計算論壇hadoop專區; http://bbs.chinacloud.cn/showforum-16.aspx
中科院計算所辦的hadoop:http://www.hadooper.cn/
1.3 資料及研究成果
http://code.google.com/p/mycloub/
我會搜集更多更好的資料,方便交流。
第2章 hadoop基本命令
2.1 hadoop基本命令
直接輸入hadoop得到的語法文檔如下:
namenode -format format the DFS filesystem 格式化DFS文件系統
namenode -format format the DFS filesystem 運行第2個namenode
datanode run a DFS datanode 運行DFS的namenode
dfsadmin run a DFS admin client 運行一個DFS的admin客戶端
mradmin run a Map-Reduce admin client 運行一個map-reduce文件系統的檢查工具
fsck run a DFS filesystem checking utility 運行一個DFS文件系統的檢查工具
fs run a generic filesystem user client 運行一個普通的文件系統用戶客戶端
balancer run a cluster balancing utility 運行MapReduce的jobTracker節點
fetchdt fetch a delegation token from the NameNode 運行一個代理的namenode
jobtracker run the MapReduce job Tracker node 運行一個MapReduce的taskTracker節點
pipes run a Pipes job 運行一個pipes作業
tasktracker run a MapReduce task Tracker node 運行一個MapReduce的taskTracker節點
historyserver run job history servers as a standalone daemon 運行歷史服務作為一個單獨的線程
job manipulate MapReduce jobs 處理mapReduce作業
queue get information regarding JobQueues
version print the version 版本
jar <jar> run a jar file 運行一個jar
distcp <srcurl> <desturl> copy file or directories recursively 遞歸地復制文件或者目錄
archive -archiveName NAME -p <parent path> <src>* <dest> create a hadoop archive
生成一個hadoop檔案
daemonlog get/set the log level for each daemon 獲取或設置每個daemon的log級別
2.2 hadoop核心內容
Hadoop框架中最核心的設計就是:MapReduce和HDFS。
l MapReduce的思想是由Google的一篇論文所提及而被廣為流傳的,簡單的一句話解釋MapReduce就是“任務的分解與結果的匯總”。
l HDFS是Hadoop分布式文件系統(Hadoop Distributed File System)的縮寫,為分布式計算存儲提供了底層支持。
2.3 為什么選擇hadoop
下面列舉hadoop主要的一些特點:
1)擴容能力(Scalable):能可靠地(reliably)存儲和處理千兆字節(PB)數據。
2)成本低(Economical):可以通過普通機器組成的服務器群來分發以及處理數據。這些服務器群總計可達數千個節點。
3)高效率(Efficient):通過分發數據,hadoop可以在數據所在的節點上並行地(parallel)處理它們,這使得處理非常的快速。
4)可靠性(Reliable):hadoop能自動地維護數據的多份復制,並且在任務失敗后能自動地重新部署(redeploy)計算任務。
2.4 HDFS設計特點
下面說說HDFS的幾個設計特點(對於框架設計值得借鑒):
1. Block的放置
默認不配置。一個Block會有三份備份,一份放在NameNode指定的DataNode,另一份放在與指定DataNode非同一Rack上的DataNode,最后一份放在與指定DataNode同一Rack上的DataNode上。
備份無非就是為了數據安全,考慮同一Rack的失敗情況以及不同Rack之間數
據拷貝性能問題就采用這種配置方式。
2. 心跳檢測
心跳檢測DataNode的健康狀況,如果發現問題就采取數據備份的方式來保證數據的安全性。
3. 數據復制
數據復制(場景為DataNode失敗、需要平衡DataNode的存儲利用率和需要平衡DataNode數據交互壓力等情況) 這里先說一下,:使用HDFS的balancer命令,
可以配置一個Threshold來平衡每一個DataNode磁盤利用率。例如設置了Threshold為10%,那么執行balancer命令的時候,
首先統計所有DataNode的磁盤利用率的均值,然后判斷如果某一個DataNode的磁盤利用率超過這個均值Threshold以上,那么將會把這個DataNode的block轉移到磁盤利用率低的DataNode,這對於新節點的加入來說十分有用。
4. 數據校驗:
采用CRC32作數據交驗。在文件Block寫入的時候除了寫入數據還會寫入交驗信息,在讀取的時候需要交驗后再讀入。
5. NameNode是單點
如果失敗的話,任務處理信息將會記錄在本地文件系統和遠端的文件系統中。
6. 數據管道性的寫入
當客戶端要寫入文件到DataNode上,首先客戶端讀取一個Block然后寫到第一個DataNode上,然后由第一個DataNode傳遞到備份的DataNode上,一直到所有需要寫入這個Block的DataNode都成功寫入,客戶端才會繼續開始寫下一個Block。
7. 安全模式
安全模式主要是為了系統啟動的時候檢查各個DataNode上數據塊的有效性,同時根據策略必要的復制或者刪除部分數據塊。
在分布式文件系統啟動的時候,開始的時候會有安全模式,當分布式文件系統處於安全模式的情況下,文件系統中的內容不允許修改也不允許刪除,
直到安全模式結束。運行期通過命令也可以進入安全模式。在實踐過程中,系統啟動的時候去修改和刪除文件也會有安全模式不允許修改的出錯提示,只需要等待一會兒即可。
2.5 說說MapReduce
MapReduce從它名字上來看就大致可以看出個緣由,兩個動詞Map和Reduce,“Map(展開)”就是將一個任務分解成為多個任務,“Reduce”就是將分解后多任務處理的結果匯總起來,得出最后的分析結果。
具體過程序如下:
1) Input輸入
從文件中讀取原始數據
原始數據 <InputKey, InputValue>
2) Map映射
將原始數據映射成用於Reduce的數據
<InputKey, InputValue> List<<MapKey, MapValue>>
3) Reduce合並
將相同Key值的中間數據合並成最終數據
<MapKey, List<MapValue>> <OutputKey, OutputValue>
4) Output輸出
將最終處理結果輸出到文件
<OutputKey, OutputValue> 結果文件
上述就是MapReduce大致處理過程,在Map前還可能會對輸入的數據有Split(分割)的過程,保證任務並行效率,在Map之后還會有Shuffle(混合)的過程,對於提高Reduce的效率以及減小數據傳輸的壓力有很大的幫助。后面會具體提及這些部分的細節。
再來看看hadoop下的MapReduce
最簡單的 MapReduce 應用程序至少包含 3 個部分:一個 Map 函數、一個 Reduce函數和一個 main 函數。main 函數將作業控制和文件輸入/輸出結合起來。在這點上,Hadoop 提供了大量的接口和抽象類,從而為 Hadoop 應用程序開發人員提供許多工具,可用於調試和性能度量等。
MapReduce 本身就是用於並行處理大數據集的軟件框架。
MapReduce 的根源是函數性編程中的 map 和 reduce 函數。它由兩個可能包含有許多實例(許多 Map 和Reduce)的操作組成。Map 函數接受一組數據並將其轉換為一個鍵/值對列表,輸入域中的每個元素對應一個鍵/值對。Reduce 函數接受 Map 函數生成的列表,然后根據它們的鍵(為每個鍵生成一個鍵/值對)縮小鍵/值對列表。
2.6 hadoop結構示意圖
MapReduce從它名字上在Hadoop的系統中,會有一台Master,主要負責NameNode的工作以及JobTracker的工作。
JobTracker的主要職責就是啟動、跟蹤和調度各個Slave的任務執行。還會有多台Slave,每一台Slave通常具有DataNode的功能並負責TaskTracker的工作。TaskTracker根據應用要求來結合本地數據執行Map任務以及Reduce任務。
第3章 FSShell 命令指南
3.1 FSShell 命令指南
調用文件系統(FS)Shell 命令應使用 bin/hadoop fs<args>的形式。所有的的 FSshell命令使用 URI 路徑作為參數。URI 格式是 scheme://authority/path。對 HDFS 文件系統,scheme 是 hdfs,對本地文件系統,scheme 是 file。其中 scheme 和 authority 參數都是可選的,如果未加指定,就會使用配置中指定的默認 scheme。一個 HDFS 文件或目錄比如/parent/child可以表示成 hdfs://namenode:namenodeport/parent/child,或者更簡單的/parent/child(假設你配置文件中的默認值是 namenode:namenodeport)。大多數 FSShell命令的行為和對應的 UnixShell 命令類似,不同之處會在下面介紹各命令使用詳情時指出。
出錯信息會輸出到 stderr,其他信息輸出到 stdout。
1) cat
使用方法:hadoop fs -catURI[URI...]
將路徑指定文件的內容輸出到 stdout。
示例:
hadoop fs-cat hdfs://host1:port1/file1hdfs://host2:port2/file2
hadoop fs-cat file:///file3/user/hadoop/file4
返回值:
成功返回 0,失敗返回-1。
2) copyFromLocal
使用方法:hadoop fs -copyFromLocal<localsrc>URI 除了限定源路徑是一個本地文件外,和 put 命令相似。
3) copyToLocal
使用方法:hadoop fs -copyToLocal[-ignorecrc][-crc]URI<localdst>
除了限定目標路徑是一個本地文件外,和 get 命令類似。
4) cp
使用方法:hadoopfs-cpURI[URI...]<dest>
將文件從源路徑復制到目標路徑。這個 Hadoop Shell 命令允許有多個源路徑,此時目標路徑必須是一個目錄。
示例:
Hadoopfs –cp /user/hadoop/file1/user/hadoop/file2
hadoopfs –cp /user/hadoop/file1/user/hadoop/file2/user/hadoop/dir
返回值:
成功返回 0,失敗返回-1。
5) du
使用方法:hadoop fs –du URI[URI...]
此 Hadoop Shell 命令顯示目錄中所有文件的大小,或者當只指定一個文件時,顯示此文件的大小。
示例:
Hadoop fs –du
/user/hadoop/dir1/user/hadoop/file1hdfs://host:port/user/hadoop/dir1
返回值:
成功返回 0,失敗返回-1。
6) dus
使用方法:hadoop fs -dus<args>
顯示文件的大小。
7) expunge
使用方法:hadoop fs -expunge
清空回收站。請參考 HDFS 設計文檔以獲取更多關於回收站特性的信息。
8) get
使用方法:hadoop fs -get[-ignorecrc][-crc]<src><localdst>
復制文件到本地文件系統。可用-ignorecrc 選項復制 CRC 校驗失敗的文件。使用-crc 選項
復制文件以及 CRC 信息。
示例:
hadoop fs –get /user/hadoop/filelocalfile
hadoop fs –get hdfs://host:port/user/hadoop/filelocalfile
返回值:
成功返回 0,失敗返回-1。Hadoop Shell 命令還有很多,這里只介紹了其中的一部分。
第4章 eclipse測試hadoop
4.1 配置eclipse
下載插件hadoop-1.03,拷貝到eclipse插件目錄
啟動hadoop
然后運行jps,看是否服務都已經啟動
啟動eclipse
配置hadoop,選擇window->preferences->Hadoop Map/Reduce,選擇hadoop安裝路徑
編輯map/reduce location
然后新建map/reduce工程
新建類
PutMerge.java
public class PutMerge { /** * @throws IOException * @Title: main * @Description: 測試逐一讀取inputFiles中的文件,並寫入目標HDFS文件 * @param args * 設定文件 * @return void 返回類型 * @throws */ public static void main(String[] args) throws IOException { Configuration conf = new Configuration(); FileSystem local = FileSystem.getLocal(conf); /** 設定文件的輸入輸出目錄 */ Path inputDir = new Path(args[0]); Path hdfsFile = new Path(args[1]); // 偽分布式下這樣處理 FileSystem hdfs = hdfsFile.getFileSystem(conf); // 正常分布式 // FileSystem hdfs = FileSystem.get(conf); try { FileStatus[] inputFiles = local.listStatus(inputDir); FSDataOutputStream out = hdfs.create(hdfsFile); for (int i = 0; i < inputFiles.length; i++) { System.out.println(inputFiles[i].getPath().getName()); FSDataInputStream in = local.open(inputFiles[i].getPath()); byte buffer[] = new byte[256]; int bytesRead = 0; while ((bytesRead = in.read(buffer)) > 0) { out.write(buffer, 0, bytesRead); } in.close(); } out.close(); } catch (IOException e) { e.printStackTrace(); } } }
在本地創建input文件夾,創建file01,file02文件
配置java application,加入參數
加入本地路徑和服務器上的路徑
然后運行程序,得到輸出結果
file02
file01
使用命令查看
bin/hadoop fs -ls /user
查看文件上傳情況