MapReduce設計模式學習

Thinkgamer_gyt發表於2016-03-12

一:概要模式

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:倒排索引概要

          適用場景:通常用在需要快速搜尋查詢響應的場景,可以對一個查詢結果進行預處理並儲存在一個資料庫中

         倒排索引實戰1         倒排索引實戰2

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顯示為null
2:右外連線
     和做外連線相反
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)關於JobControl


2:鏈摺疊

鏈摺疊是應用於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的實現依賴於資料是如何儲存的


相關文章