(一)hadoop學習:大體框架和流程理解

學習Hadoop有一段時間了,主要是通過《Hadoop權威指南》,同時參考了網上的很多文章。靜下心來,盤點下這一段時間的收穫,歸納總結,做一個學習筆記,因爲可以記錄的東西實在太多了,所以這裏就着重記錄我在學習過程中花費比較多時間去理解的內容。

說到Hadoop就不能不提到Lucene和Nutch。Lucene並不是一個應用程序,只是提供了一個Java的全文索引引擎工具包,可以方便的嵌入到各種實際應用中實現全文搜索、索引功能。Nutch是一個以Lucene爲基礎實現的搜索引擎應用。在Nutch0.8.0版本之前,Hadoop還屬於Nutch的一部分,而從Nutch0.8.0開始,將其中實現的NDFS和MapReduce剝離出來成立一個新的開源項目,這就是Hadoop。Hadoop中實現了Google的GFS和MapReduce算法,使之成爲了一個分佈式的計算平臺。

Hadoop不僅僅是一個用於存儲的分佈式文件系統,而且是設計用來在由通用計算設備組成的大型集羣上執行分佈式應用的框架。

1.       HDFS

先來看看HDFS,即Hadoop Distributed FileSystem。它是爲以流的方式存取大文件而設計的,適用於幾百MB,GB以及TB,並一次寫入多次讀取的場合。HDFS是爲達到高數據吞吐量而優化的,這有可能會以延遲爲代價,所以,對於低延時數據訪問、大量小文件、同時寫和任意的文件修改,它並不是十分適合。

HDFS是以block-sizedchunk組織其文件內容的,默認的block大小爲64MB。與單一磁盤上的文件系統不同的是,HDFS中小於一個塊大小的文件不會佔據整個塊的空間。構成HDFS主要是Namenode(master)和一系列的Datanodes(workers)。Namenode是管理HDFS的目錄樹和相關的文件元數據,這些信息是以“namespaceimage”和“editlog”兩個文件形式存放在本地磁盤,但這些文件是在HDFS每次重啓的時候重新構造出來。Datanode則是存取文件實際內容的節點,Datanodes會定時地將block的列表彙報給Namenode。

Namenode是元數據存放的地方,所以其錯誤容忍能力相當重要,一般使用將元數據持久存儲在本地或遠程的機器上,或使用secondarynamenode來定期同步Namenode的元數據。如果Namenode出現了故障,一般會將原Namenode中持久化的元數據拷貝到secondarynamenode中,使secondary namenode作爲新的Namenode運行。

HDFS的結構如圖 1所示。從圖中可以看到,Namenode,Datanode,Client之間的通信都是建立在TCP/IP的基礎之上。當Client要執行一個讀取操作的時候,向遠程的Namenode發起RPC請求,Namenode會視情況返回文件的部分或全部block列表;對每個block,Namenode都會返回有該block拷貝的Datanode地址,客戶端開發庫會選取離客戶端最接近的Datanode來讀取block;讀完當前block後,關閉與當前Datanode連接,爲讀取下一個block尋找最佳Datanode;讀取完一個block都會進行checksum驗證,如果讀取有誤,Client會通知Namenode,然後再從下一批擁有該block拷貝的Datanode繼續讀取。

 



2.       Map-Reduce

Map-Reduce是一個使用簡易的軟件框架,基於它寫出來的應用程序能夠運行在大型集羣上,並以一種可靠容錯的方式並行處理TB級別的數據集。Map-Reduce把分佈式的業務邏輯從複雜的細節(如何分佈,調度,監控及容錯等)中抽離出來,使程序員可以只關心應用邏輯,關心根據哪些key把問題分解,哪些操作是map操作,哪些是reduce操作,其它並行計算中的分佈、工作調度、機器間通信等問題都交給Map-ReduceFramework去做,很大程度上簡化了整個編程模型。

一個Map-Reduce 作業(job) 通常會把輸入的數據集切分爲若干獨立的數據塊,由 map任務(task)以完全並行的方式處理它們。框架會對map的輸出先進行排序,然後把結果輸入給reduce任務。通常作業的輸入和輸出都會被存儲在文件系統中。整個框架負責任務的調度和監控,以及重新執行已經失敗的任務。Map過程通過對輸入列表中的每一條記錄執行map函數,生成一系列的輸出列表,如圖2。Reduce過程對一個輸入的列表進行掃描工作,隨後生成一個聚集值,最爲最後的輸出,如圖3。若map的輸出進行了分區處理,則在同一個分區的數據將被髮送到同一個Reduce任務中。



                                     

整個MapReduce的數據流程如圖4所示。



圖4 MapReduce數據流程

數據從map函數輸出到作爲reduce函數的輸入的過程被稱爲shuffle(混洗或洗牌)。在這個過程中,框架對數據進行了很多處理,有人將shuffle稱爲MapReduce的心臟,是奇蹟發生的地方。我在學習這裏的時候也是花了比較長的時間去理解。瞭解shuffle如何工作,對於優化MapReduce大有幫助。



Map函數產生的輸出結果,不是簡單的將它寫到磁盤,這個過程更復雜。每個map任務都有一個環形內存緩衝區,任務會把輸出寫到此,當緩衝內容達到指定大小時,一個後臺進程開始把內容溢寫到磁盤中。在溢寫過程中,map的輸出將會繼續被寫入緩衝區中,但如果緩衝區在這時滿了,那map就會阻塞直到溢寫完成。在寫到磁盤之前,線程首先對數據分區已決定將數據發送到哪一個reduce任務。在每個分區中,後臺線程按鍵進行內排序。

Reduce任務首先要複製取得map任務輸出,map任務可以不再同一時間完成,所以只要有一個任務結束,reduce任務就開始複製其輸出。內存緩衝區達到閾值大小或達到map輸出閾值時,會被合併,進而被溢寫到磁盤中。隨着磁盤上的副本增多,後臺線程將他們合併成一個更大的,排好序的文件,這將是reduce函數真正的輸入文件。Reduce階段的合併階段也被稱爲排序階段,它的具體操作與map階段的內排序有所不同,我在理解這點的時候就出現了很多問題。

以WordCount爲例,看看mapreduce的執行過程和shuffle的流程。假設有640M的文件,默認block大小爲64M,10臺hadoop機器,使用5個reduce任務:

1、每個map任務按行讀取文件,讀取的行數據交給map函數執行,每一行數據調用一次map函數,以單詞爲key,以1爲value輸出。

2、   如果有combiner,就對第一步的輸出進行combiner操作。它將map輸出結果做一次歸併,將相同word的計數累加。這樣可以將中間結果大大減少,減少後續partitioner,sort, copy的開銷,提高性能。

3、  每個map任務對自己的輸出進行分區,默認的分區操作是對key進行hash,並對reduce任務數(5)求餘,這樣相同的單詞都被分在同一分區內。之後將對同一分區內的數據按key進行排序,使之成爲各分區內有序。

4、  Reduce任務各自從map機器上copy屬於自己的文件,並且進行合併。合併好後進行sort操作,再次把不同小文件中的同一單詞聚合在一起,作爲提供給reduce操作的數據。

5、  進行reduce操作,對同一個單詞的value列表再次進行累加,最終得到每個單詞的詞頻數。

6、  最後Reduce把結果寫到磁盤。

3.       Hadoop I/O

Hadoop附帶了一個基本類型的數據集的I/O,其中某些技術比Hadoop本身更具普遍意義。在這裏只總結下和MapReduce框架緊密相關的InputFormat和OutputFormat,以及SequenceFile和MapFile文件。

Hadoop中的MapReduce框架依賴InputFormat提供數據,依賴OutputFormat輸出數據;每一個MapReduce程序都離不開他們。Hadoop提供了一系列InputFormat和OutputFormat方便開發。

TextInputFormat:用於讀取純文本文件,文件被分爲一系列以LF或CR結束的行,key是每一行的偏移量(LongWritable),value是每一行的內容(Text)。

KeyValueTextInputFormat:用於讀取文件,如果行被分隔符分割爲兩部分,第一部分爲key,剩下的爲value;若沒有分隔符,整行作爲key,value爲空。

SequenceFileInputFormat:用於讀取SequenceFile。關於SequenceFile後面再說。

SequenceFileInputFilter:根據filter從SequenceFile中取得滿足條件的數據,通過setFilterClass指定Filter,內置了三種Filter,RegexFilter取key值滿足指定的正則表達式的記錄;PercentFilter通過指定參數f,取記錄行數f%==0的記錄;MD5Filter通過指定參數f,取MD5(key)%f==0的記錄。

TextOutputFormat:輸出到純文本文件,格式爲key +“   ”+ value。

NullOutputFormat:hadoop中的/dev/null,將輸出送進黑洞。

SequenceFileOutputFormat,輸出SequenceFile文件。

MultipleSequenceFileOutputFormat,MultipleTextOutputFormat:根據key將記錄輸出到不同的文件。

SequenceFile &MapFile

序列化(serialization)指的是將結構化對象轉爲字節流以便於通過網絡進行傳輸或寫入持久存儲的過程。序列化用於分佈式數據處理中兩個截然不同的領域:1、進程進通信,2、持久存儲。SequenceFile類爲二進制鍵/值對提供一個持久化的數據結構。其實在Map-Reduce過程中,map處理文件的臨時輸出就是用SequenceFile處理過的。

雖然很多MapReduce程序都是用writable鍵/值類型,但這並不是MapReduce的API指定的,事實上,任何類型都可以用,只要每種類型都可以轉換爲二進制表示並從二進制表示中轉換出來。

理解好SequenceFile,MapFile就容易明白了,它其實是經過排序的帶着索引的SequenceFile,可以根據鍵進行查找。將SequenceFile進行排序,再創建索引即可轉換爲MapFile。

Hadoop的內部工作機制是複雜的,相互依賴的,因爲它運行在分佈式系統的理論、實用技術和技術常識這些複雜的基礎之上。學習Hadoop也將是一個漫長的過程,以上只是我在這段時間的一點學習總結,希望能在工作中不斷地深入理解hadoop的思想,並將其運用到實際工作中。


引用:http://blog.sina.com.cn/s/blog_502c8cc40100o3dn.html

發佈了41 篇原創文章 · 獲贊 9 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章