一:概要模式
1:簡(jiǎn)介
概要設(shè)計(jì)模式更接近簡(jiǎn)單的MR應(yīng)用,因?yàn)榛阪I將數(shù)據(jù)分組是MR范型的核心功能,所有的鍵將被分組匯入reducer中
本章涉及的概要模式有數(shù)值概要(numerical summarization),倒排索引(inverted index),計(jì)數(shù)器計(jì)數(shù)(counting with counter)2:概要設(shè)計(jì)模式包含
2.1:關(guān)于Combiner和paritioner
combiner:reducer之前調(diào)用reducer函數(shù),對(duì)數(shù)據(jù)進(jìn)行聚合,極大的減少通過(guò)網(wǎng)絡(luò)傳輸?shù)絩educer端的key/value數(shù)量,適用的條件是你可以任意的改變值的順序,并且可以隨意的將計(jì)算進(jìn)行分組,同時(shí)需要注意的是一個(gè)combiner函數(shù)只對(duì)一個(gè)map函數(shù)有作用
partitioner:許多概要模式通過(guò)定制partitioner函數(shù)實(shí)現(xiàn)更優(yōu)的將鍵值對(duì)分發(fā)到n個(gè)reducer中,著這樣的需求場(chǎng)景會(huì)比較少,但如果任務(wù)的執(zhí)行時(shí)間要求很高,數(shù)據(jù)量非常大,且存在數(shù)據(jù)傾斜的情況,定制partitioner將是非常有效的解決方案
源碼分析請(qǐng)點(diǎn)擊 編程實(shí)例請(qǐng)點(diǎn)擊
2.2:數(shù)值概要模式
2.2.1:數(shù)值概要模式:計(jì)算數(shù)據(jù)聚合統(tǒng)計(jì)的一般性模式 2.2.2:數(shù)值概要應(yīng)用的場(chǎng)景需要滿足以下亮點(diǎn): 1:要處理的數(shù)據(jù)是數(shù)值數(shù)據(jù)或者計(jì)數(shù) 2:數(shù)據(jù)可以按照某些特定的字段分組 2.2.3:適用場(chǎng)景:
1:?jiǎn)卧~計(jì)數(shù) (可以使用combiner) 2:最大值/最小值/計(jì)數(shù) (可以使用combiner) 3:平均值 (可以使用combiner,但必須做相應(yīng)的處理,即迂回算法,舉例如下) 給定用戶的評(píng)論列表,按天計(jì)算每小時(shí)的評(píng)論長(zhǎng)度 Map:context.write(1,tuple(1,1小時(shí)的平均長(zhǎng)度)) reducer: 處理:sum += tulpe.gethour * tuple.getavrg count += tuple.gethour 輸出: key=1 value=sum/count 4:中位數(shù)/標(biāo)準(zhǔn)差2.3:倒排索引概要
適用場(chǎng)景:通常用在需要快速搜索查詢響應(yīng)的場(chǎng)景,可以對(duì)一個(gè)查詢結(jié)果進(jìn)行預(yù)處理并存儲(chǔ)在一個(gè)[數(shù)據(jù)庫(kù)](http://lib.csdn.net/base/mysql)中
[倒排索引實(shí)戰(zhàn)1](http://blog.csdn.net/gamer_gyt/article/details/47101351) [倒排索引實(shí)戰(zhàn)2](http://blog.csdn.net/gamer_gyt/article/details/50014143)
2.4:計(jì)數(shù)器計(jì)數(shù)
已知應(yīng)用
統(tǒng)計(jì)記錄數(shù):簡(jiǎn)單的對(duì)指定時(shí)間段的記錄數(shù)進(jìn)行統(tǒng)計(jì)是很常見(jiàn)的,統(tǒng)計(jì)小數(shù)量級(jí)的唯一實(shí)例計(jì)數(shù) 匯總:用來(lái)執(zhí)行對(duì)數(shù)據(jù)的某些字段進(jìn)行匯總
二:過(guò)濾模式
1:簡(jiǎn)介
過(guò)濾模式也可以被認(rèn)為是一種搜索形式,如果你對(duì)找出所有具備特定信息的記錄感興趣,就可以過(guò)濾掉不匹配搜索條件的其他記錄,與大多數(shù)基礎(chǔ)模式類似,過(guò)濾作為一種抽象模式為其他模式服務(wù),過(guò)濾簡(jiǎn)單的對(duì)某一條記錄進(jìn)行評(píng)估,并基于某個(gè)條件作出判斷,以確定當(dāng)前這條記錄是保留還是丟棄
2:適用場(chǎng)景
2.1:過(guò)濾, 使用過(guò)濾的唯一必要條件是數(shù)據(jù)可以被解析成記錄,并可以通過(guò)非常特定的準(zhǔn)則來(lái)確定它們是否需要保留,不需要reducer函數(shù)
近距離觀察數(shù)據(jù):準(zhǔn)備一個(gè)特定的子集,子集中的記錄有某些共同屬性或者具備某些有趣的特性,需要進(jìn)一步深入的分析。
跟蹤某個(gè)事件的線索:從一個(gè)較大數(shù)據(jù)集中抽取一個(gè)連續(xù)事件作為線索來(lái)做案例研究。
分布式grep:通過(guò)一個(gè)正則表達(dá)式匹配每一行,輸出滿足條件的行
數(shù)據(jù)清理:數(shù)據(jù)有時(shí)是畸形的,不完整的 或者是格式錯(cuò)誤的,過(guò)濾可以用于驗(yàn)證每一條數(shù)據(jù)是否滿足記錄,將不滿足的數(shù)據(jù)刪除
** 簡(jiǎn)單隨機(jī)抽樣:可以使用隨機(jī)返回True or False的評(píng)估函數(shù)做過(guò)濾,可以通過(guò)調(diào)小true返回的概率實(shí)現(xiàn)對(duì)結(jié)果集合大小的控制
** 移除低分值數(shù)據(jù):將不滿足某個(gè)特定閥值的記錄過(guò)濾出去
2.2:布隆過(guò)濾, 對(duì)每一條記錄,抽取其中一個(gè)特征,如果抽取的特性是布隆過(guò)濾中所表示的值的集合成員,則保留記錄
移除大多數(shù)不受監(jiān)視的值:最直接的使用案例是清楚不感興趣的值
對(duì)成本很高的集合成員資格檢查做數(shù)據(jù)的預(yù)先過(guò)濾:
2.3:Top10,不管輸入數(shù)據(jù)的大小是多少,你都可以精確的知道輸出的結(jié)果的記錄數(shù)
異類分析:
選取感興趣的數(shù)據(jù):
引人注目的指標(biāo)面板:
2.4:去重,過(guò)濾掉數(shù)據(jù)集中的相似數(shù)據(jù),找出唯一的集合
數(shù)據(jù)去重: 代碼舉例
抽取重復(fù)值:
規(guī)避內(nèi)連接的數(shù)據(jù)膨脹:
三:數(shù)據(jù)組織模式
1:分層結(jié)構(gòu)模式
分層模式是從數(shù)據(jù)中創(chuàng)造出不同于原結(jié)構(gòu)的新紀(jì)錄 適用場(chǎng)景:數(shù)據(jù)源被外部鏈接,數(shù)據(jù)是結(jié)構(gòu)化的并且是基于行的 <MultipleInputs類:用于指定多個(gè)Mapper任務(wù)進(jìn)行不同格式文件的輸入>2:分區(qū)和分箱模式
分區(qū):將記錄進(jìn)行分類(即分片,分區(qū)或者分箱),但他并不關(guān)心記錄的順序,目地是將數(shù)據(jù)集中相似的記錄分成不同的,更小的數(shù)據(jù)集,在該模式下數(shù)據(jù)是通過(guò)自定義Map的分區(qū)器進(jìn)行分區(qū)的。 分箱:是在不考慮記錄順序的情況下對(duì)記錄進(jìn)行分類,目的是將數(shù)據(jù)集中每條記錄歸檔到一個(gè)或者多個(gè)舉例 兩者的不同之處在于分箱是在Map階段對(duì)數(shù)據(jù)進(jìn)行拆分,其好處是減少reduce的工作量,通常使資源分布更有效,缺點(diǎn)是每個(gè)mapper將為每個(gè)可能輸出的箱子創(chuàng)建文件,對(duì)后續(xù)的分析十分不利3:全排序和混排模式
全排序:關(guān)注的是數(shù)據(jù)從記錄到記錄的順序,目的是能夠按照指定的鍵進(jìn)行并行排序。適用的范圍是排序的鍵必須具有可比性只有這樣數(shù)據(jù)才能被排序 混排序:關(guān)注記錄在數(shù)據(jù)集中的順序,目的是將一個(gè)給定的記錄完全隨機(jī)化4:數(shù)據(jù)生成模式
四:連接模式
SQL連接模式包括內(nèi)連接和外連接eg:A表 B表 內(nèi)連接:只連接兩個(gè)表中都用的外鍵連接(eg 以ID作為連接鍵,只連接有相同ID) 外連接:1:做外連接 以用戶ID為外鍵的A+B做外連接 以A表為基準(zhǔn),A表數(shù)據(jù)全部顯示,B表中不在A表中的ID顯示為null2:右外連接 和做外連接相反3:全外連接 左外連接和右外連接的合并,有相同ID 的顯示,沒(méi)有相同ID的顯示為NULL 反連接:全外連接減去內(nèi)連接的結(jié)果1:reduce端連接:
相當(dāng)其他連接模式來(lái)講用時(shí)最長(zhǎng),但是也是實(shí)現(xiàn)簡(jiǎn)單并且支持所有不同類型的操作 適用場(chǎng)景:1:多個(gè)大數(shù)據(jù)需要按一個(gè)外鍵做鏈接操作,如果除了一個(gè)數(shù)據(jù)集以外,其他所有的數(shù)據(jù)集都可以放入內(nèi)存,可以嘗試使用復(fù)制連接 2:你需要靈活的執(zhí)行任意類型的連接操作 等效的SQL:Select user.id,user.location,comment.uprotes from user [inner | left | right] join comments on user.id=comments.userid 優(yōu)化方案:可以使用布隆過(guò)濾器執(zhí)行reduce端的連接2:復(fù)制連接:
是一種特殊類型的連接操作,是在一個(gè)打的數(shù)據(jù)集和許多小的數(shù)據(jù)集之間通過(guò)MAP端執(zhí)行的連接的操作,該模式完全消除了混排數(shù)據(jù)到reduce的需求 適用場(chǎng)景: 1:要執(zhí)行的連接類型是由內(nèi)連接或者左外連接,且大的輸入數(shù)據(jù)集在連接操作符的“左邊”時(shí) 2:除一個(gè)大的數(shù)據(jù)集外,所有的數(shù)據(jù)集都可以存入每個(gè)Map任務(wù)的內(nèi)存中 性能分析:因?yàn)椴恍枰猺educe,因此在所有連接模式是最快的一種,代價(jià)是數(shù)據(jù)量,數(shù)據(jù)要能完全的儲(chǔ)存在JVM中,這極大的受限于你愿意為每個(gè)Map和reduce分配多少內(nèi)存 3:組合連接:
是一種非常特殊的連接操作,他可以在map端對(duì)許多非常大的格式化輸入做連接,需要預(yù)先組織好的或者是使用特定的方式預(yù)處理過(guò)的,即在使用這個(gè)類型的連接操作之前,必須按照外鍵對(duì)數(shù)據(jù)集進(jìn)行排序個(gè)分區(qū),并以一種非常特殊的方式讀入數(shù)據(jù)集 Hadoop通過(guò)CompositeInputFormat來(lái)支持組合連接方式 僅適用于內(nèi)連接和全外連,每一個(gè)mapper的輸入都需要按照指定的方式做分區(qū)和排序,對(duì)于每一個(gè)輸入數(shù)據(jù)集都要分成相同數(shù)目的分區(qū),此外,對(duì)應(yīng)于某個(gè)特定的外鏈所做的所有記錄必須處于同一分區(qū)中 通常情況下這發(fā)生在幾個(gè)作業(yè)的輸出有相同數(shù)量的reducer和相同的外鍵,并且輸出文件是不可拆分的即不大于一個(gè)hdfs文件快的大小或是gzip壓縮的 適用場(chǎng)景: 1:需要執(zhí)行的是內(nèi)連接或者全外連接 2:所有的數(shù)據(jù)集都足夠大 3:所有的數(shù)據(jù)集都可以用相同的外鍵當(dāng)mapper的輸入鍵讀取 4:所有的數(shù)據(jù)集有相同的數(shù)據(jù)的分區(qū) 5:數(shù)據(jù)集不會(huì)經(jīng)常改變 6:每一個(gè)分區(qū)都是按照外鍵排序的,并且所有的外鍵都出現(xiàn)在關(guān)聯(lián)分區(qū)的每個(gè)數(shù)據(jù)集中4:笛卡爾積:
是一種有效的將多個(gè)輸入源的滅一個(gè)記錄跟所有其他記錄配對(duì)的方式適用場(chǎng)景: 1:需要分析各個(gè)記錄的所有配對(duì)之間的關(guān)系 2:沒(méi)有其他方法可以解決這個(gè)問(wèn)題 3:對(duì)執(zhí)行時(shí)間沒(méi)有限制 等效的SQL:SELECT * FROM t1,t2 等效的PIG:CROSS a,b;
五:元模式
關(guān)于模式的模式1:作業(yè)鏈
針對(duì)MapReduce處理小的文件時(shí),優(yōu)化的辦法是可以在作業(yè)中始終執(zhí)行CombineFileInputFormat加載間歇性的輸出,在進(jìn)入mapper處理之前,CombineFileInputFormat會(huì)將小的塊組合在一起形成較大的輸入split當(dāng)執(zhí)行做個(gè)作業(yè)的作業(yè)鏈時(shí),可以使用job.submit方法代替job.waitForCompletion()來(lái)并行的啟動(dòng)多個(gè)作業(yè),調(diào)用submit方法后會(huì)立即返回至當(dāng)前線程,而作業(yè)在后臺(tái)運(yùn)行,該方法允許一次執(zhí)行多個(gè)任務(wù), job.isComplete()是檢查一個(gè)作業(yè)是否完成的非阻塞方法,該方法可以通過(guò)不斷輪詢的方式判斷所有作業(yè)是否完成如果檢測(cè)到一個(gè)依賴的作業(yè)失敗了,此時(shí)你應(yīng)該退出整個(gè)作業(yè)鏈,而不是試圖讓他繼續(xù)示例:(1)基本作業(yè)(2)并行作業(yè)鏈(3)關(guān)于Shelll腳本(4)關(guān)于JobControl2:鏈折疊
鏈折疊是應(yīng)用于MapReduce作業(yè)鏈的一種優(yōu)化方法,基本上他是一個(gè)經(jīng)驗(yàn)法則,即每一條記錄都可以提交至多個(gè)mapper或者一個(gè)reducer,然后再交給一個(gè)mapper這種合并處理能夠減少很多讀取文件和傳輸數(shù)據(jù)的時(shí)間,作業(yè)鏈的這種結(jié)構(gòu)使得這種方法是可行的,因?yàn)閙ap階段是完全無(wú)法共享的,因此map并不關(guān)心數(shù)據(jù)的組織形式和或者數(shù)據(jù)有沒(méi)有分組,在構(gòu)建大的作業(yè)鏈時(shí),通過(guò)將作業(yè)鏈折疊,使得map階段合并起來(lái)帶來(lái)很大的性能提升鏈折疊的主要優(yōu)點(diǎn)是減少mapreduce管道中移動(dòng)的數(shù)據(jù)量作業(yè)鏈中有許多模式,可以通過(guò)下面介紹的這些方法來(lái)查找和確認(rèn)哪些可以折疊(1)看看作業(yè)鏈的map階段,如果多個(gè)map階段是相鄰的,將他們合并到一個(gè)階段(2)如果作業(yè)鏈?zhǔn)且詍ap階段結(jié)束,將這個(gè)階段移動(dòng)到前一個(gè)reducer里邊,他除去了寫(xiě)臨時(shí)數(shù)據(jù)的IO操作,然后在reduce中執(zhí)行只有map的作業(yè),這同一也能減少任務(wù)啟動(dòng)的開(kāi)銷(3)注意,作業(yè)鏈的第一個(gè)map階段無(wú)法 從下一個(gè)優(yōu)化中獲益,盡可能的在減少數(shù)據(jù)量(如過(guò)濾)的操作和增加數(shù)據(jù)量(如豐富)的操作之間拆分每個(gè)map階段(合并或者其他)注意:(1)合并階段需要大量的內(nèi)存,例如將5個(gè)復(fù)制連接合并在一起可能不是一個(gè)好的選擇,因?yàn)樗麑⒖赡艹^(guò)任務(wù)可用的總內(nèi)存,在這些情況下,最好將這些操作分開(kāi)(2)不管一個(gè)作業(yè)是不是作業(yè)鏈,都要盡早盡可能的去過(guò)濾掉更多的數(shù)據(jù),mr作業(yè)開(kāi)銷最大的部分通常都是管道推送數(shù)據(jù):加載數(shù)據(jù),混排/排序階段,以及存儲(chǔ)數(shù)據(jù)實(shí)現(xiàn)折疊鏈有兩種主要方法:(1)手動(dòng)裁剪然后將代碼粘貼在一起(2)使用特殊類ChainMapper和ChainReducer(特殊類介紹參考:http://www.iteye.com/topic/1134144)3:作業(yè)歸并
和作業(yè)鏈折疊一樣,作業(yè)歸并是另一種減少M(fèi)R管道IO管道的優(yōu)化方法,通過(guò)作業(yè)歸并可以使得加載同一份數(shù)據(jù)的兩個(gè)不相關(guān)作業(yè)共享MR管道,作業(yè)歸并最主要的優(yōu)點(diǎn)是數(shù)據(jù)只需要加載和解析一次。先決條件是:兩個(gè)作業(yè)必須有相同的中間鍵和輸出格式,因?yàn)樗麄儗⒐蚕砉艿溃蚨枰褂孟嗤臄?shù)據(jù)類型,如果這的確是一個(gè)問(wèn)題的話,可以使用序列化或者多態(tài),但會(huì)增加復(fù)制度作業(yè)歸并步驟如下:(1)將兩個(gè)mapper代碼放在一起(2)在mapper中生成鍵和值時(shí),需要用標(biāo)簽加以標(biāo)記,以區(qū)別map源(3)在reducer中,在解析出標(biāo)簽后使用if語(yǔ)句切換到相應(yīng)的reducer代碼中去執(zhí)行(4)使用multipleOutputs將作業(yè)的輸出分來(lái)
六:輸入輸出模式
自定義輸入與輸出
在Hadoop自定義輸入和輸出
Hadoop允許用戶修改從磁盤(pán)加載數(shù)據(jù)的方式,修改方式有兩種:
1:配置如何根據(jù)HDFS的塊生成連續(xù)的輸入分塊,配置記錄在map階段如何實(shí)現(xiàn)。
為此將要用到的兩個(gè)類即,RecordReader和InputFormat
2:hadoop也允許用戶通過(guò)類似的方式修改數(shù)據(jù)的存儲(chǔ)形式
通過(guò)OutputFormat和RecordWriter實(shí)現(xiàn)
1:生成數(shù)據(jù)
這個(gè)模式下是只有Map的
(1)InputFormat憑空創(chuàng)建split
(2)RecordReader讀入虛的split并根據(jù)他生成隨機(jī)記錄
(3)某些情況下,能夠在split中賦予一些信息,告訴recordreader生成什么
(4)通常情況下,IdentityMap僅僅將讀入的數(shù)據(jù)原樣輸出
2:外部源輸出
外部源輸出詳細(xì)描述:在作業(yè)提交之前,OutputFormat將驗(yàn)證作業(yè)配置中指定的輸出規(guī)范。RecordReader負(fù)責(zé)將所有的鍵值對(duì)寫(xiě)入外部源
性能分析:必須小心數(shù)據(jù)接收者能否處理并行連接。有1000個(gè)任務(wù)將數(shù)據(jù)寫(xiě)入到單個(gè)SQL數(shù)據(jù)庫(kù)中,者=這工作起來(lái)并不好,為避免這種情況你可能不得不讓每個(gè)reducer多處理一些數(shù)據(jù)以減少寫(xiě)入到數(shù)據(jù)接收者的并行度,如果數(shù)據(jù)接收者支持并行寫(xiě)入,那么這未必是個(gè)問(wèn)題。
3:外部源輸入
在MapReduce中數(shù)據(jù)是以并行的方式加載而不是以串行的方式,為了能夠大規(guī)模的讀取數(shù)據(jù),源需要有定義良好的邊界
MR實(shí)現(xiàn)該模式的瓶頸將是數(shù)據(jù)源或網(wǎng)絡(luò),數(shù)據(jù)源對(duì)于多連接可能不具很好的擴(kuò)展性,同時(shí)給定的數(shù)據(jù)源可能與MR集群的網(wǎng)絡(luò)不在同一個(gè)網(wǎng)絡(luò)環(huán)境下
4:分區(qū)裁剪
分區(qū)裁剪模式將通過(guò)配置決定框架如何選取輸入split以及如何基于文件名過(guò)濾加載到MR作業(yè)的文件
描述:分區(qū)裁剪模式是在InputFormat中實(shí)現(xiàn)的,其中g(shù)etsplit方法是我們需要特別注意的,因?yàn)樗_定了要?jiǎng)?chuàng)建的輸入split,進(jìn)而確定map任務(wù)的個(gè)數(shù), RecordReader的實(shí)現(xiàn)依賴于數(shù)據(jù)是如何存儲(chǔ)的