對關于hadoop的文檔及資料進行進一步的整理。
毋庸置疑 http://hadoop.apache.org/
國内 http://www.hadoopor.com/ 專門研究hadoop的,《hadoop開發者》由該站創辦,已發4期
中國雲計算論壇hadoop專區; http://bbs.chinacloud.cn/showforum-16.aspx
中科院計算所辦的hadoop:http://www.hadooper.cn/
我會搜集更多更好的資料,友善交流。
直接輸入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級别
hadoop架構中最核心的設計就是:mapreduce和hdfs。
l mapreduce的思想是由google的一篇論文所提及而被廣為流傳的,簡單的一句話解釋mapreduce就是“任務的分解與結果的彙總”。
l hdfs是hadoop分布式檔案系統(hadoop distributed file system)的縮寫,為分布式計算存儲提供了底層支援。
下面列舉hadoop主要的一些特點:
1)擴容能力(scalable):能可靠地(reliably)存儲和處理千兆位元組(pb)資料。
2)成本低(economical):可以通過普通機器組成的伺服器群來分發以及處理資料。這些伺服器群總計可達數千個節點。
3)高效率(efficient):通過分發資料,hadoop可以在資料所在的節點上并行地(parallel)處理它們,這使得處理非常的快速。
4)可靠性(reliable):hadoop能自動地維護資料的多份複制,并且在任務失敗後能自動地重新部署(redeploy)計算任務。
下面說說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上資料塊的有效性,同時根據政策必要的複制或者删除部分資料塊。
在分布式檔案系統啟動的時候,開始的時候會有安全模式,當分布式檔案系統處于安全模式的情況下,檔案系統中的内容不允許修改也不允許删除,
直到安全模式結束。運作期通過指令也可以進入安全模式。在實踐過程中,系統啟動的時候去修改和删除檔案也會有安全模式不允許修改的出錯提示,隻需要等待一會兒即可。
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 函數生成的清單,然後根據它們的鍵(為每個鍵生成一個鍵/值對)縮小鍵/值對清單。
mapreduce從它名字上在hadoop的系統中,會有一台master,主要負責namenode的工作以及jobtracker的工作。
jobtracker的主要職責就是啟動、跟蹤和排程各個slave的任務執行。還會有多台slave,每一台slave通常具有datanode的功能并負責tasktracker的工作。tasktracker根據應用要求來結合本地資料執行map任務以及reduce任務。
調用檔案系統(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
5) du
使用方法:hadoop fs –du uri[uri...]
此 hadoop shell 指令顯示目錄中所有檔案的大小,或者當隻指定一個檔案時,顯示此檔案的大小。
hadoop fs –du
/user/hadoop/dir1/user/hadoop/file1hdfs://host:port/user/hadoop/dir1
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 指令還有很多,這裡隻介紹了其中的一部分。
下載下傳插件hadoop-1.03,拷貝到eclipse插件目錄
啟動hadoop
然後運作jps,看是否服務都已經啟動
啟動eclipse
配置hadoop,選擇window->preferences->hadoop map/reduce,選擇hadoop安裝路徑
編輯map/reduce location
然後建立map/reduce工程
建立類
putmerge.java
<code>public</code> <code>class</code> <code>putmerge {</code>
<code> </code><code>/**</code>
<code> </code><code>* @throws ioexception</code>
<code> </code><code>* @title: main</code>
<code> </code><code>* @description: 測試逐一讀取inputfiles中的檔案,并寫入目标hdfs檔案</code>
<code> </code><code>* @param args</code>
<code> </code><code>* 設定檔案</code>
<code> </code><code>* @return void 傳回類型</code>
<code> </code><code>* @throws</code>
<code> </code><code>*/</code>
<code> </code><code>public</code> <code>static</code> <code>void</code> <code>main(string[] args)</code><code>throws</code> <code>ioexception {</code>
<code> </code><code>configuration conf =</code><code>new</code> <code>configuration();</code>
<code> </code><code>filesystem local = filesystem.getlocal(conf);</code>
<code> </code><code>/** 設定檔案的輸入輸出目錄 */</code>
<code> </code><code>path inputdir =</code><code>new</code> <code>path(args[</code><code>0</code><code>]);</code>
<code> </code><code>path hdfsfile =</code><code>new</code> <code>path(args[</code><code>1</code><code>]);</code>
<code> </code><code>// 僞分布式下這樣處理</code>
<code> </code><code>filesystem hdfs = hdfsfile.getfilesystem(conf);</code>
<code> </code><code>// 正常分布式</code>
<code> </code><code>// filesystem hdfs = filesystem.get(conf);</code>
<code> </code><code>try</code> <code>{</code>
<code> </code><code>filestatus[] inputfiles = local.liststatus(inputdir);</code>
<code> </code><code>fsdataoutputstream out = hdfs.create(hdfsfile);</code>
<code> </code><code>for</code> <code>(</code><code>int</code> <code>i =</code><code>0</code><code>; i < inputfiles.length; i++) {</code>
<code> </code><code>system.out.println(inputfiles[i].getpath().getname());</code>
<code> </code><code>fsdatainputstream in = local.open(inputfiles[i].getpath());</code>
<code> </code><code>byte</code> <code>buffer[] =</code><code>new</code> <code>byte</code><code>[</code><code>256</code><code>];</code>
<code> </code><code>int</code> <code>bytesread =</code><code>0</code><code>;</code>
<code> </code><code>while</code> <code>((bytesread = in.read(buffer)) ></code><code>0</code><code>) {</code>
<code> </code><code>out.write(buffer,</code><code>0</code><code>, bytesread);</code>
<code> </code><code>}</code>
<code> </code><code>in.close();</code>
<code> </code><code>}</code>
<code> </code><code>out.close();</code>
<code> </code><code>}</code><code>catch</code> <code>(ioexception e) {</code>
<code> </code><code>e.printstacktrace();</code>
<code> </code><code>}</code>
<code> </code><code>}</code>
<code>}</code>
在本地建立input檔案夾,建立file01,file02檔案
配置java application,加入參數
加入本地路徑和伺服器上的路徑
然後運作程式,得到輸出結果
file02
file01
使用指令檢視
bin/hadoop fs -ls /user
檢視檔案上傳情況