hive優化之控制hive任務中的reduce數

2021-07-01 22:59:52 字數 1680 閱讀 6505

1.    hive自己如何確定reduce數:

reduce個數的設定極大影響任務執行效率,不指定reduce個數的情況下,hive會猜測確定乙個reduce個數,基於以下兩個設定:

hive.exec.reducers.bytes.per.reducer(每個reduce任務處理的資料量,預設為1000^3=1g) 

hive.exec.reducers.max(每個任務最大的reduce數,預設為999)

計算reducer數的公式很簡單n=min(引數2,總輸入資料量/引數1)

即,如果reduce的輸入(map的輸出)總大小不超過1g,那麼只會有乙個reduce任務;

如:select pt,count(1) from popt_tbaccountcopy_mes where pt = '2012-07-04' group by pt; 

/group/p_sdo_data/p_sdo_data_etl/pt/popt_tbaccountcopy_mes/pt=2012-07-04 總大小為9g多,因此這句有10個reduce

2.    調整reduce個數方法一:

調整hive.exec.reducers.bytes.per.reducer引數的值;

set hive.exec.reducers.bytes.per.reducer=500000000; (500m)

select pt,count(1) from popt_tbaccountcopy_mes where pt = '2012-07-04' group by pt; 這次有20個reduce

3.    調整reduce個數方法二;

set mapred.reduce.tasks = 15;

select pt,count(1) from popt_tbaccountcopy_mes where pt = '2012-07-04' group by pt;這次有15個reduce

4.    reduce個數並不是越多越好;

同map一樣,啟動和初始化reduce也會消耗時間和資源;

另外,有多少個reduce,就會有多少個輸出檔案,如果生成了很多個小檔案,那麼如果這些小檔案作為下乙個任務的輸入,則也會出現小檔案過多的問題;

5.    什麼情況下只有乙個reduce;

很多時候你會發現任務中不管資料量多大,不管你有沒有設定調整reduce個數的引數,任務中一直都只有乙個reduce任務;

其實只有乙個reduce任務的情況,除了資料量小於hive.exec.reducers.bytes.per.reducer引數值的情況外,還有以下原因:

a)    沒有group by的彙總,比如把select pt,count(1) from popt_tbaccountcopy_mes where pt = '2012-07-04' group by pt; 寫成 select count(1) from popt_tbaccountcopy_mes where pt = '2012-07-04';

這點非常常見,希望大家盡量改寫。

b)    用了order by

c)    有笛卡爾積

通常這些情況下,除了找辦法來變通和避免,我暫時沒有什麼好的辦法,因為這些操作都是全域性的,所以hadoop不得不用乙個reduce去完成;

同樣的,在設定reduce個數的時候也需要考慮這兩個原則:使大資料量利用合適的reduce數;使單個reduce任務處理合適的資料量;

Hive任務優化(2)

1.大多數情況下,hive會對每對join連線物件啟動乙個mapreduce任務。2.多表關聯時,如果每個on子句都使用相同的連線鍵的話,那麼只會產生乙個mapreduce job。3.hive總是按照從左到右的順序執行。hive會假定最後一張表是最大的表,在對每行記錄進行連線操作時,它會將其他表進...

hive 幾種hive優化方法

1.通過explain或者explain extended來檢視執行計畫。explain select from u3 執行結果 stage dependencies stage 0 is a root stage stage plans stage stage 0 fetch operator l...

Hive知識之優化技巧

1 用group by替換distinct去重select user name from trade group by user name 2 使用mapjoinselect mapjoin table a a.b.from table a a join table b b on a.id b.id...