薛博召
摘 要 Hadoop是由Apache基金會開發的分布式計算架構,用戶可以在不了解分布式底層細節的情況下開發分布式程序,充分利用集群的威力進行高速運算和存儲。Hadoop框架最核心的設計就是:HDFS和MapReduce,HDFS為海量的數據提供了存儲,而MapReduce則為海量的數據提供了計算。
關鍵詞 大數據;Hadoop;HDFS;MapReduce
引言
Hadoop是一個能夠對大量數據進行分布式處理的框架,它有可靠、高效、可擴展等特性。可靠是因為它假設計算和存儲元素可能失敗,通過維護多個工作數據副本,確保能夠對失敗節點重新進行分布處理。高效是因為它以并行的方式工作,通過并行處理加快處理速度、提高吞吐量。通過靈活的橫向擴展能夠處理 PB 級數據。
1 Hadoop技術架構研究
HDFS和MapReduce是Hadoop的兩大核心。HDFS被設計成適合運行在通用硬件上的分布式文件系統,是一個高度容錯性的系統,能提供高吞吐量的數據訪問,非常適合大規模數據集上的應用。把一個文件存入HDFS,HDFS會把文件分割成多個block,分散存儲在N臺linux機器上,每臺存儲數據的機器稱為datanode,每一個block會在多個datanode上存儲多份副本,默認是3份。一旦文件被切塊存儲, HDFS中就必須有一個機制,來記錄用戶的每一個文件的切塊信息,及每一塊的具體存儲機器,namenode負責管理文件目錄、文件和block的對應關系,以及block和datanode的對應關系。
MapReduce被用于大規模集群計算,每個MapReduce作業主要包含input split、map task、combiner、shuffle和reduce task共5個階段。在進行map計算之前,MapReduce會把輸入的數據切分為若干塊,劃分切片的任務由job客戶端負責,每個輸入分片對應一個map任務。Map task階段會調用相應對象的next()方法,逐行讀取文件,產生key-value值,解析出key-value值后調用定制編寫的業務邏輯代碼,計算輸出新的key-value值后緩存,待后續處理。
Combiner階段是可選的,它是map運算的后續操作,主要是在map計算出中間文件前做合并重復key值的操作。例如對文件里的單詞頻率做統計,map計算時碰到一個”hadoop”的單詞就會記錄為1,但是這篇文章里”hadoop”可能出現多次,那么map輸出文件就會冗余,因此在reduce計算前對相同的key做合并操作,文件會變小,可有效提高寬帶傳輸效率。但是,combiner操作是有風險的,求總數、最大值、最小值可以使用combiner,如果做平均值計算使用combiner,最終reduce計算結果就會出錯。
將map task生成的數據傳輸給reduce task的過程就是shuffle,一般MapReduce計算的都是海量數據,內存空間有限,map輸出時不可能把所有文件都放到內存,因此map過程涉及將數據寫入磁盤。map輸出時會在內存開啟環形緩沖區,默認大小是100MB,配置文件里默認設定為了緩沖區閥值是0.8。map會為輸出操作啟動一個守護線程(Spiller),若緩沖區內存使用達到了80%,這個守護線程就會把內容寫到磁盤,這個過程叫spill。另外20%內存可以繼續寫入數據,寫入磁盤和寫入內存操作互不干擾,如果緩存滿了,那么map作業會阻塞寫入內存的操作,讓寫入磁盤操作完成后再繼續執行寫入內存操作。map task在寫入磁盤前還會執行分區和排序操作,如果我們定義了combiner函數,那么排序前還會執行combiner操作。分區會調用Partitioner的組件,排序則會調用key上的CompareTo()來比大小。每次spill操作時就會寫一個文件,這個文件叫溢出文件,溢出文件里區號小的在前面,同區中按key有序。map輸出全部做完后,map會合并這些輸出文件,這些文件也是分區且有序的。合并過程中會產生一個分區索引文件,用來指明每個分區的起始點以及它的偏移量。Partitioner操作和map階段的輸入分片很像,一個Partitioner對應一個reduce作業。Partitioner就是reduce的輸入分片,這個可以編程控制,主要是根據實際業務場景,達到更好的reduce負載均衡,這是提高reduce效率的關鍵。
map task階段完成后,程序就會退出,那么reduce task要去哪里獲取處理完的數據呢?答案是這些文件會被納入NodeManager web程序的document目錄中,reduce task會通過web服務器下載相應區號的文件,將這些文件合并。處理數據時,首先實現繼承自Reducer的類,里面有一個reduce(k,迭代器,context)方法,通過反射構造出一個對象去調用reduce(),里面的參數k和迭代器會分別去創建一個對象,每迭代一次就會按文件里的順序去讀一次,然后把讀出來的k傳給對象k,然后把v傳給對象values里。這個過程就是從磁盤上把二進制數據讀取出來,然后反序列化把數據填入對象的一個過程。迭代過程中會有一個分組比較器(Grouping Comparator)去判斷迭代的k是否相同,不同則終止迭代。每迭代完一次,context.write()輸出一次聚合后的結果,這個聚合的結果會通過TextOutputFormat類的getRecordWriter()方法拿到一個RecordWriter對象,通過這個對象去調一個write(k,v)方法,將這些數據以文件的方式寫入HDFS[1]。
2 結束語
Hadoop提供了一套久經考驗的批處理模型,適合處理對時間要求不高的大規模數據集。通過低成本組件即可搭建完整功能的Hadoop集群,使得這一廉價且高效的處理技術可以靈活應用在很多案例中。
參考文獻
[1] 張偉.基于Hadoop的大數據分析管理平臺架構設計[J].信息技術與網絡安全,2018,37(11):30-33,57.