Hive優化系列之Map與Reduce數量選擇

注意,以下操作都是針對非分桶表

map數量

  • 算法
    • MapTask的個數=輸入文件總大小/分片尺寸,個人理解就是輸出的文件數量
      • 原因:系統對輸入的源文件依照Block的尺寸分片,並在執行Job時安排一個Map Task處理一個Block的
    • 或者由mapred.map.task數量決定,但是如果這個參數不合理的話,會失效
    • 小文件不分片
    • 壓縮文件無法被切分
  • 優化建議
    • 優化原因
      • map數量過少則導致併發度減小,job過長;若大量作業,則會堵塞
    • 減小map數量:合併小文件(hive0.7之後會自動合併) ,是優化的策略
      • map階段會輸出過多小文件,而初始化和創建map的開銷很大,在 block 數據量偏少的情況下,單個任務運行的時間就少,那麼任務開啓的開銷很可 能佔據總開銷的大量比例
      • 如果已知數據源中小文件過多,用戶最好在向新表導入數據之前就打開automerge 開關,使一個 Task 處理多個 block。因爲同屬一個 Task 的結果將被返回在同一個文件中,因此導入數據時做任務的合併處理可達到小文件合併效果。然後關閉automerge 開關,今後都不用再對該表開啓
      • 除了檢查 block 的大小,還可以通過在 4040 端口查看任務第一階段 Tasks 的數量和每Task 的運行時間判斷是否需要 automerge
      • 第一階段的 Task 負責 Map 端任務,默認每個Task 對應一個 block,所以如果第一階段 Task 過多而且單個執行時間短,表示小體積 block 多,Task 運行效率低,需要啓用 automerge。注意,不建議爲每個線程安排過多的 block。 在調整相關參數時注意,所設計的下限要儘量保證單個 Task 的處理時間不要低於 2s,調 整的上線不能使對應的
      • 合併之後的大小最好控制在 256M以內,能實現較好的性能(這只是個參 考值,具體情況需根據實際數據量和列數而定)
      • 查看實際運行時 GC的狀況,如果大部分 Tasks的 GC時間佔Task運行時間的 15%以內,可以合併的更多一些。GC時間可以在 4040界面觀察
      •  查看每個Task的執行時間,最好不要超過2分鐘。如果太長,很可能 會產生 GC問題和拖尾效應,即某個 Task過長而導致的整體運行時間 過長。這時應適當增加 Task
      • 選取 automerge參數時,在設計下限的時候,儘量保證單個 Task 的處理時間不要低於 2s
    • 增加map數量:上一個job的reduce
reduce數量
  • 過少:如果數據量很大,會導致這個reduce異常的慢,從而導致這個任務不能結束,也有可能會OOM
  • 過多:產生的小文件太多,合併起來代價太高,namenode的內存佔用也會增大。如果我們不指定mapred.reduce.tasks, hive會自動計算需要多少個reducer
  • 由map端數據複製到Reduce端的數據大小決定
  • 有很多任務是沒有reduce的過程的
  • 可以通過設置mapred.reduce.task來控制reduce數
  • Hive的估計機制很弱,不指定reducer個數的情況下,Hive會猜測確定一個reducer個數,基於以下兩個設定:
    • 1. hive.exec.reducers.bytes.per.reducer(默認爲1000^3)
      • 這個參數控制一個job會有多少個reducer來處理,依據的是輸入文件的總大小。默認1GB
    • 2. hive.exec.reducers.max(默認爲999)
      • 如果 input / bytes per reduce > max  則會啓動這個參數所指定的reduce個數。  這個並不會影響mapre.reduce.tasks參數的設置
  • 計算reducer數的公式很簡單:N=min(參數2,總輸入數據量/參數1)
  • 通常情況下,有必要手動指定reducer個數。考慮到map階段的輸出數據量通常會比輸入有大幅減少,因此即使不設定reducer個數,重設參數2還是必要的。依據Hadoop的經驗,可以將參數2設定爲0.95*(集羣中TaskTracker個數)
  • 通常(不是絕對),大表 JOIN或者 GROUPBY後,產生的數據量相對原始數據小很多。這時可以減少後面 ReduceTask的數目,使 Reduce Task的啓動 更有價值
  • 針對 GROUP BY、JOIN、INRTERSACT、EXCEPT、EXTRACT 這五個操作,改變兩個 Task數目比例分別對應的語句:
    • SEThive.groupby.aggregateratio=0.6;
    • SEThive.join.aggregateratio=1.0;
    • SEThive.intersect.aggregateratio=1.0;
    • SEThive.except.aggregateratio=1.0;
    • SEThive.extract.aggregateratio=1.0;
小文件過多時參數設置
  • set ngmr.partition.automerge=true;
  • set ngmr.partition.mergesize.mb=-1
    • 合併以後每個task最多處理的數據量大小,-1表示關閉該參數
    • 默認8M;優先級大於ngmr.partition;mergesize
    • 設置一個Block大小,單位MB,-1默認不執行
    • 可以根據任務設置大小,比如200、300等
  • set ngmr.partition.mergesize=3;
    • 表示將 n 個 block 安排給單個線程處理
    • 參數3代表當前3個tasks合併成一個task
    • 可以根據需要僅設置這兩個參數(mergesize.mb)其中之一,默認使用方法 mergesize.mb來控制
    • 如果需要使用方法 mergesize,需要將 mergesize.mb 設爲-1。 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章