注意,以下操作都是針對非分桶表
map數量
- 算法
- MapTask的個數=輸入文件總大小/分片尺寸,個人理解就是輸出的文件數量
- 原因:系統對輸入的源文件依照Block的尺寸分片,並在執行Job時安排一個Map Task處理一個Block的
- 或者由mapred.map.task數量決定,但是如果這個參數不合理的話,會失效
- 小文件不分片
- 壓縮文件無法被切分
- MapTask的個數=輸入文件總大小/分片尺寸,個人理解就是輸出的文件數量
- 優化建議
- 優化原因
- 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異常的慢,從而導致這個任務不能結束,也有可能會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參數的設置
- 1. hive.exec.reducers.bytes.per.reducer(默認爲1000^3)
- 計算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。