hive性能優(yōu)化

Hive性能優(yōu)化:

hive分配map和reduce數(shù)量

m,r數(shù)據(jù)量,對(duì)效率影響較大,因?yàn)樵趩?dòng)和初始化階段是很耗費(fèi)時(shí)間和資源的。

(1)控制mapper的數(shù)據(jù)量

通常情況下,作業(yè)會(huì)通過input的目錄產(chǎn)生一個(gè)或多個(gè)map任務(wù),

主要決定的因素有:input的文件總個(gè)數(shù),input的文件大小

Eg:

a) 假設(shè)input目錄下有1個(gè)文件a,大小為780M,那么hadoop會(huì)將該文件a分隔成7個(gè)塊(block為128M,6個(gè)128m的塊和1個(gè)12m的塊),從而產(chǎn)生7個(gè)map數(shù)

b) 假設(shè)input目錄下有3個(gè)文件a,b,c,大小分別為10m,20m,130m,那么hadoop會(huì)分隔成4個(gè)塊(10m,20m,128m,2m),從而產(chǎn)生4個(gè)map數(shù)

兩種方式控制map數(shù)量:

通過合并小文件來實(shí)現(xiàn)

合并小文件參數(shù)屬性:

(1)是否合并Map輸出文件:hive.merge.mapfiles=true(默認(rèn)值為真)

(2)是否合并Reduce 端輸出文件:hive.merge.mapredfiles=false(默認(rèn)值為假)

(3)合并文件的大小:hive.merge.size.per.task=25610001000(默認(rèn)值為256000000)

通過控制上一個(gè)job的reduce數(shù)量來控制

(2)控制reducer的數(shù)據(jù)量

? Reducer的個(gè)數(shù)極大的影響執(zhí)行效率,不指定reducer個(gè)數(shù)的情況下,hive分配reducer個(gè)數(shù)基于以下:

[if !supportLists](1)??????[endif]參數(shù)1:hive.exec.reducers.bytes.per.reducer(默認(rèn)為1G)

[if !supportLists](2)??????[endif]參數(shù)2 :hive.exec.reducers.max(默認(rèn)為999)

計(jì)算reducer數(shù)的公式

N=min(參數(shù)2,總輸入數(shù)據(jù)量/參數(shù)1)

或者直接指定reducer個(gè)數(shù):setmapred.reduce.tasks=13;?? //但是效果不是很好

???? Reducer個(gè)數(shù)不是越多越好,同map一樣,啟動(dòng)和初始化reduce也會(huì)消耗時(shí)間和資源;有多少個(gè)reduce就有多少個(gè)輸出文件

??????Reduce數(shù)過多:生成很多小文件,如果這些小文件作為下一個(gè)任務(wù)的輸入,則會(huì)出現(xiàn)小文件過多的問題

??????Reduce過少:影響執(zhí)行效率

???? 什么情況下只會(huì)有一個(gè)reduce:

???????很多時(shí)候會(huì)發(fā)現(xiàn),任務(wù)重不管數(shù)據(jù)量有多大,不管有沒有調(diào)整reduce的個(gè)數(shù),任務(wù)重一直都只有一個(gè)reduce

(1)? ? 數(shù)據(jù)量小于hive.exec.reducers.bytes.per.reducer參數(shù)值的情況外

(2)? ?沒有g(shù)roup by的匯總

(3)? ? 用了order by


2.關(guān)于join:

(1)將數(shù)據(jù)量少的表或者子查詢放在join的左邊,

原因:在join操作的reduce階段,位于join左邊的表的數(shù)據(jù)會(huì)被加載進(jìn)內(nèi)存,將數(shù)據(jù)量少的表放在左側(cè),可以有效減少內(nèi)存溢出的概率

注:如果多個(gè)join操作,且每個(gè)表參與多個(gè)join的字段相同,則將所有的join合并到一個(gè)mapperd程序中

Eg:

//在一個(gè)mapre程序中執(zhí)行join

SELECT a.val, b.val, c.val

FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key1)? ?

//在兩個(gè)mapred程序中執(zhí)行join

SELECT a.val, b.val, c.val

FROM a JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key2)??

Eg2中會(huì)在兩個(gè)mapper中執(zhí)行,是由于參與兩次join的表b的key不一致


(2) Map join的關(guān)鍵在于join操作中的某個(gè)表的數(shù)據(jù)量很小,join操作在map中完成,不再需要reduce

Eg:

SELECT /*+ MAPJOIN(b) */ a.key,? a.value

? FROM a join b on a.key =? b.key

注:mapjoin無法執(zhí)行a full/right outer join b 操作、

相關(guān)參數(shù):

hive.join.emit.interval= 1000

hive.mapjoin.size.key= 10000

hive.mapjoin.cache.numrows = 10000


???? 注:在進(jìn)行join操作的條件過濾的時(shí)候,應(yīng)該講過濾條件放在on關(guān)鍵詞里面,這樣可以提高效率

??????原因:join操作是在where操作之前執(zhí)行,所以在執(zhí)行join時(shí),where條件并不能起到減少join數(shù)據(jù)的作用


3.group by優(yōu)化

????? Map端聚合,首先在map端進(jìn)行初步的聚合,最后在reduce端得出最終結(jié)果。

??? 相關(guān)參數(shù):

(1)? hive.map.aggr = true? //是否在 Map 端進(jìn)行聚合,默認(rèn)為True

(2)? hive.groupby.mapaggr.checkinterval

= 100000 //在 Map 端進(jìn)行聚合操作的條目數(shù)目

?????數(shù)據(jù)傾斜的聚合優(yōu)化,對(duì)數(shù)據(jù)進(jìn)行聚合優(yōu)化,可以進(jìn)行參數(shù)設(shè)置:

???????hive.groupby.skewindata = true


當(dāng)此項(xiàng)設(shè)定為 true,生成的查詢計(jì)劃會(huì)有兩個(gè) MR Job。第一個(gè) MR Job 中,Map 的輸出結(jié)果集合會(huì)隨機(jī)分布到 Reduce 中,每個(gè) Reduce 做部分聚合操作,并輸出結(jié)果,這樣處理的結(jié)果是相同的 Group By Key 有可能被分發(fā)到不同的 Reduce 中,從而達(dá)到負(fù)載均衡的目的;第二個(gè) MR Job 再根據(jù)預(yù)處理的數(shù)據(jù)結(jié)果按照Group

? By Key 分布到 Reduce 中(這個(gè)過程可以保證相同的 Group

? By Key 被分布到同一個(gè) Reduce 中),最后完成最終的聚合操作。



4. 如何調(diào)整map數(shù)量

?通常有一下參數(shù)可以決定map的數(shù)量

set mapred.max.split.size=256000000;??????? --決定每個(gè)map處理的最大的文件大小,單位為B

set mapred.min.split.size.per.node=1;???????? --節(jié)點(diǎn)中可以處理的最小的文件大小

set mapred.min.split.size.per.rack=1;???????? --機(jī)架中可以處理的最小的文件大小


沒有辦法直接控制map的數(shù)量,只能通過以上參數(shù)的設(shè)置來控制map的分配數(shù)量

set mapred.max.split.size=1024000000;

setmapred.min.split.size.per.node=1024000000;

setmapred.min.split.size.per.rack=1024000000;


 可以簡(jiǎn)單的理解為集群對(duì)一個(gè)表分區(qū)下面的文件進(jìn)行分發(fā)到各個(gè)節(jié)點(diǎn),之后根據(jù)mapred.max.split.size確認(rèn)要啟動(dòng)多少個(gè)map數(shù),邏輯如下??   a.假設(shè)有兩個(gè)文件大小分別為(256M,280M)被分配到節(jié)點(diǎn)A,那么會(huì)啟動(dòng)兩個(gè)map,剩余的文件大小為10MB和35MB因?yàn)槊總€(gè)大小都不足241MB會(huì)先做保留??   b.根據(jù)參數(shù)set

? mapred.min.split.size.per.node看剩余的大小情況并進(jìn)行合并,如果值為1,表示a中每個(gè)剩余文件都會(huì)自己起一個(gè)map,這里會(huì)起兩個(gè),如果設(shè)置為大于45*1024*1024則會(huì)合并成一個(gè)塊,并產(chǎn)生一個(gè)map??   如果mapred.min.split.size.per.node為10*1024*1024,那么在這個(gè)節(jié)點(diǎn)上一共會(huì)有4個(gè)map,處理的大小為(245MB,245MB,10MB,10MB,10MB,10MB),余下9MB??   如果mapred.min.split.size.per.node為45*1024*1024,那么會(huì)有三個(gè)map,處理的大小為(245MB,245MB,45MB)??   實(shí)際中mapred.min.split.size.per.node無法準(zhǔn)確地設(shè)置成45*1024*1024,會(huì)有剩余并保留帶下一步進(jìn)行判斷處理??   c. 對(duì)b中余出來的文件與其它節(jié)點(diǎn)余出來的文件根據(jù)mapred.min.split.size.per.rack大小進(jìn)行判斷是否合并,對(duì)再次余出來的文件獨(dú)自產(chǎn)生一個(gè)map處理

重點(diǎn):注意各參數(shù)的設(shè)置大小,不要沖突,否則會(huì)異常,大小順序如下?

mapred.max.split.size <= mapred.min.split.size.per.node

<= mapred.min.split.size.per.rack?

調(diào)整reduce數(shù)量,不建議隨意設(shè)置reduce參數(shù),可能調(diào)整參數(shù)更好一點(diǎn)?

set hive.exec.reducers.bytes.per.reducer=1073741824

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容