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