Hive控制Reduce個數

2021-07-03 07:29:09 字數 3998 閱讀 3900

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 wherept = '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 bypt; 這次有20個reduce

3. 調整reduce個數方法二;

set mapred.reduce.tasks = 15;

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

4. reduce

個數並不是越多越好;

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

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

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

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

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

a) 沒有group by的彙總,比如把selectpt,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

是將符合sql語法的字串解析生成可以在hadoop上執行的mapreduce的工具。

使用hive盡量按照分布式計算的一些特點來設計sql,和傳統關係型資料庫有區別,

所以需要去掉原有關係型資料庫下開發的一些固有思維。

基本原則: 1

:盡量盡早地過濾資料,減少每個階段的資料量,對於分割槽表要加分割槽,同時只選擇需要使用到的字段

select ... froma

join b

on a.key =b.key

wherea.userid>10

andb.userid<10

anda.dt='20120417'

andb.dt='20120417';

應該改寫為:

select ....from (select .... from a

wheredt='201200417'

anduserid>10

) ajoin ( select.... from b

wheredt='201200417'

and userid <10

) bon a.key =b.key; 2

:盡量原子化操作,盡量避免乙個sql包含複雜邏輯

可以使用中間表來完成複雜的邏輯

drop table ifexists tmp_table_1;

create table ifnot exists tmp_table_1 as

select ......;

drop table ifexists tmp_table_2;

create table ifnot exists tmp_table_2 as

select ......;

drop table ifexists result_table;

create table ifnot exists result_table as

select ......;

drop table ifexists tmp_table_1;

drop table ifexists tmp_table_2; 3

:單個sql所起的job個數盡量控制在5個以下 4

:慎重使用mapjoin,一般行數小於2000行,大小小於1m(擴容後可以適當放大)的表才能使用,小表要注意放在join的左邊(目前tcl裡面很多都小表放在join的右邊)。

否則會引起磁碟和記憶體的大量消耗 5

:寫sql要先了解資料本身的特點,如果有join ,group操作的話,要注意是否會有資料傾斜

如果出現資料傾斜,應當做如下處理:

sethive.exec.reducers.max=200;

setmapred.reduce.tasks= 200;---

增大reduce個數

sethive.groupby.mapaggr.checkinterval=100000 ;--

這個是group的鍵對應的記錄條數超過這個值則會進行分拆,值根據具體資料量設定

set hive.groupby.skewindata=true;--

如果是group by過程出現傾斜 應該設定為true

sethive.skewjoin.key=100000; --

這個是join的鍵對應的記錄條數超過這個值則會進行分拆,值根據具體資料量設定

sethive.optimize.skewjoin=true;--

如果是join 過程出現傾斜 應該設定為true 6

:如果union all的部分個數大於2,或者每個union部分資料量大,應該拆成多個insert into 語句,實際測試過程中,執行時間能提公升50%

insert overwitetable tablename partition (dt= ....)

select .....from (

select ... froma

union all

select ... fromb

union all

select ... fromc

) rwhere ...;

可以改寫為:

insert intotable tablename partition (dt= ....)

select ....from a

where ...;

insert intotable tablename partition (dt= ....)

select ....from b

where ...;

insert intotable tablename partition (dt= ....)

select ....from c

where ...;

Hive 設定map 和 reduce 的個數

一 控制hive任務中的map數 1.通常情況下,作業會通過input的目錄產生乙個或者多個map任務。主要的決定因素有 input的檔案總個數,input的檔案大小,集群設定的檔案塊大小 目前為128m,可在hive中通過set dfs.block.size 命令檢視到,該引數不能自定義修改 2....

Hive 設定map 和 reduce 的個數

一 控制hive任務中的map數 1.通常情況下,作業會通過input的目錄產生乙個或者多個map任務。主要的決定因素有 input的檔案總個數,input的檔案大小,集群設定的檔案塊大小 目前為128m,可在hive中通過set dfs.block.size 命令檢視到,該引數不能自定義修改 2....

hive實現設定reduce個數的方法

1.hive自己如何確定reduce數 reduce個數的設定極大影響任務執行效率,不指定reduce個數的情況下,hive會猜測確定乙個reduce個數,基於以下兩個設定 hive.exec.reducers.bytes.per.reducer 每個reduce任務處理的資料量,預設為1000 3...