天天看點

《Hadoop實戰第2版》——1.4節Hadoop與分布式開發

1.4 hadoop與分布式開發

我們通常所說的分布式系統其實是分布式軟體系統,即支援分布式處理的軟體系統。它是在通信網絡互聯的多處理機體系結構上執行任務的系統,包括分布式作業系統、分布式程式設計語言及其編譯(解釋)系統、分布式檔案系統和分布式資料庫系統等。hadoop是分布式軟體系統中檔案系統層的軟體,它實作了分布式檔案系統和部分分布式資料庫系統的功能。hadoop中的分布式檔案系統hdfs能夠實作資料在計算機叢集組成的雲上高效的存儲和管理,hadoop中的并行程式設計架構mapreduce能夠讓使用者編寫的hadoop并行應用程式運作得以簡化。下面簡單介紹一下基于hadoop進行分布式并發程式設計的相關知識,詳細的介紹請參看後面有關mapreduce程式設計的章節。

hadoop上并行應用程式的開發是基于mapreduce程式設計模型的。mapreduce程式設計模型的原理是:利用一個輸入的key/value 對集合來産生一個輸出的key/value 對集合。mapreduce庫的使用者用兩個函數來表達這個計算:map和reduce。

使用者自定義的map函數接收一個輸入的key/value 對,然後産生一個中間key/value 對的集合。mapreduce把所有具有相同key值的value集合在一起,然後傳遞給reduce函數。

使用者自定義的reduce函數接收key和相關的value集合。reduce函數合并這些value值,形成一個較小的value集合。一般來說,每次調用reduce函數隻産生0或1個輸出的value值。通常我們通過一個疊代器把中間value值提供給reduce函數,這樣就可以處理無法全部放入記憶體中的大量的value值集合了。

圖1-4是mapreduce的資料流圖,展現mapreduce 處理大資料集的過程。簡而言之,這個過程就是将大資料集分解為成百上千個小資料集,每個(或若幹個)資料集分别由叢集中的一個節點(一般就是一台普通的計算機)進行處理并生成中間結果,然後這些中間結果又由大量的節點合并,形成最終結果。圖1-4也說明了mapreduce架構下并行程式中的兩個主要函數:map、reduce。在這個結構中,使用者需要完成的工作是根據任務編寫map和reduce兩個函數。

《Hadoop實戰第2版》——1.4節Hadoop與分布式開發

mapreduce計算模型非常适合在大量計算機組成的大規模叢集上并行運作。圖1-4中的每一個map任務和每一個reduce任務均可以同時運作于一個單獨的計算節點上,可想而知,其運算效率是很高的,那麼這樣的并行計算是如何做到的呢?下面将簡單介紹一下其原理。

資料分布存儲

hadoop分布式檔案系統(hdfs)由一個名位元組點(namenode)和多個資料節點 (datanode)組成,每個節點都是一台普通的計算機。在使用方式上hdfs與我們熟悉的單機檔案系統非常類似,利用它可以建立目錄,建立、複制、删除檔案,并且可以檢視檔案内容等。但檔案在hdfs底層被切割成了block,這些block分散地存儲在不同的datanode上,每個block還可以複制數份資料存儲在不同的datanode上,達到容錯容災的目的。namenode則是整個hdfs的核心,它通過維護一些資料結構來記錄每一個檔案被切割成了多少個block、這些block可以從哪些datanode中獲得,以及各個datanode的狀态等重要資訊。

分布式并行計算

hadoop中有一個作為主要的 jobtracker,用于排程和管理其他的tasktracker。jobtracker可以運作于叢集中的任意一台計算機上;tasktracker則負責執行任務,它必須運作于datanode上,也就是說datanode既是資料存儲節點,也是計算節點。jobtracker将map任務和reduce任務分發給空閑的tasktracker,讓這些任務并行運作,并負責監控任務的運作情況。如果某一個tasktracker出了故障,jobtracker會将其負責的任務轉交給另一個空閑的tasktracker重新運作。

本地計算

資料存儲在哪一台計算機上,就由哪台計算機進行這部分資料的計算,這樣可以減少資料在網絡上的傳輸,降低對網絡帶寬的需求。在hadoop這類基于叢集的分布式并行系統中,計算節點可以很友善地擴充,是以它所能夠提供的計算能力近乎無限。但是資料需要在不同的計算機之間流動,故而網絡帶寬變成了瓶頸。“本地計算”是一種最有效的節約網絡帶寬的手段,業界将此形容為“移動計算比移動資料更經濟”。

任務粒度

在把原始大資料集切割成小資料集時,通常讓小資料集小于或等于hdfs中一個block 的大小(預設是64mb),這樣能夠保證一個小資料集是位于一台計算機上的,便于本地計算。假設有m個小資料集待處理,就啟動m個map任務,注意這m個map任務分布于n 台計算機上,它們将并行運作,reduce任務的數量r則可由使用者指定。

資料分割(partition)

把map任務輸出的中間結果按key的範圍劃分成r份(r是預先定義的reduce任務的個數),劃分時通常使用hash函數(如hash(key) mod r),這樣可以保證某一段範圍内的 key一定是由一個reduce任務來處理的,可以簡化reduce的過程。

資料合并(combine)

在資料分割之前,還可以先對中間結果進行資料合并(combine),即将中間結果中有相同key的對合并成一對。combine的過程與reduce的過程類似,在很多情況下可以直接使用reduce函數,但combine是作為map任務的一部分、在執行完map函數後緊接着執行的。combine能夠減少中間結果中對的數目,進而降低網絡流量。

reduce

map任務的中間結果在執行完combine和partition之後,以檔案形式存儲于本地磁盤上。中間結果檔案的位置會通知主要jobtracker,jobtracker再通知reduce任務到哪一個tasktracker上去取中間結果。注意,所有的map任務産生的中間結果均按其key值通過同一個hash函數劃分成了r份,r個reduce任務各自負責一段key區間。每個reduce需要向許多個map任務節點取得落在其負責的key區間内的中間結果,然後執行reduce函數,形成一個最終的結果檔案。

任務管道

有r個reduce任務,就會有r個最終結果。很多情況下這r個最終結果并不需要合并成一個最終結果,因為這r個最終結果又可以作為另一個計算任務的輸入,開始另一個并行計算任務,這也就形成了任務管道。

這裡簡要介紹了在并行程式設計方面hadoop中mapreduce程式設計模型的原理、流程、程式結構和并行計算的實作,mapreduce程式的詳細流程、程式設計接口、程式執行個體等請參見後面章節。