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