hive性能優(yōu)化及參數(shù)調(diào)優(yōu)

記錄一下自己在工作中經(jīng)常用到的幾個(gè)參數(shù)設(shè)置,從調(diào)整的實(shí)際效果看還是有效果的。

企業(yè)相關(guān)服務(wù)器資源配置:平均600臺(tái)active的節(jié)點(diǎn),

每個(gè)節(jié)點(diǎn)可用的內(nèi)存在200G左右,可用的memory total:116T

1、**set hive.exec.parallel=true;**

開(kāi)啟job的并行:基本每個(gè)hql腳本都會(huì)開(kāi)啟這個(gè)參數(shù),默認(rèn)并行度為8,

在集群資源充足的情況下,可以提高job并行的數(shù)量:

set hive.exec.parallel.thread.number=16;? (企業(yè)生產(chǎn)中我是很少用到這個(gè)的,都是用的默認(rèn)值,因?yàn)樘馁Y源怕影響別的任務(wù),搞不好會(huì)被運(yùn)維抓住,郵件通報(bào)批評(píng)!當(dāng)然使用時(shí)還是看具體情況吧!)

因?yàn)樾枨笾幸粡埍淼膉ob的數(shù)量每次基本都在20個(gè)以上,在相關(guān)維度多,涉及到的字段邏輯復(fù)雜的情況下,

一張表中job的數(shù)量會(huì)超過(guò)100個(gè),之前做的一個(gè)需求中insert插入的腳本中job的數(shù)量達(dá)到了169個(gè),

在測(cè)試環(huán)境運(yùn)行的時(shí)候只用了一個(gè)小時(shí)就跑完了,數(shù)據(jù)量在一億條左右,大概有一百多G。

2、**set hive.map.aggr=true;**

在map端中會(huì)做部分聚集操作,效率更高但需要更多的內(nèi)存,可以根據(jù)自己企業(yè)的資源情況來(lái)設(shè)置,

如果我的腳本涉及到的數(shù)據(jù)量不大的話,我一般不會(huì)開(kāi)啟這個(gè)參數(shù)。

3、**set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;**

hive0.5開(kāi)始的默認(rèn)值,執(zhí)行map前進(jìn)行小文件合并,在一個(gè)job中生成的map的數(shù)量很多的時(shí)候,

和第二個(gè)參數(shù)一起開(kāi)啟配合使用,在實(shí)際生產(chǎn)中多次驗(yàn)證發(fā)現(xiàn)可以減少一倍以上的map數(shù)量。

在開(kāi)啟前我的一個(gè)job的map數(shù)量有577個(gè),開(kāi)啟后的map的數(shù)量只有196個(gè),極大提高程序的運(yùn)行效率。

4、**set mapred.max.split.size=256000000;**

每個(gè)Map(一個(gè)切片的)最大輸入大小(這個(gè)值決定了合并后文件的數(shù)量),和第3個(gè)參數(shù)配合一起使用

默認(rèn)值也是256000000,

mapred.min.split.size默認(rèn)值是10000000

dfs.block.size默認(rèn)是128M,這個(gè)參數(shù)通過(guò)hive來(lái)更改是沒(méi)有實(shí)際用的,只能通過(guò)hdfs來(lái)修改

***實(shí)際在hive中,并不是split的大小要小于等于blocksize,而是可以遠(yuǎn)大于blocksize,為什么???(map的數(shù)量)***

<1>當(dāng)hive需要處理的文件是壓縮,且壓縮算法不支持文件切分的時(shí)候,決定map個(gè)數(shù)的因素主要是文件塊實(shí)際存儲(chǔ)的大小,

如果文件塊本身很大,比如500Mb左右,那么每個(gè)map處理的splitsize至少要是500Mb左右。

這個(gè)時(shí)候我們不能人為通過(guò)參數(shù)降低每個(gè)map的splitsize來(lái)增加map個(gè)數(shù),只能通過(guò)增加splitsize,減少map個(gè)數(shù),

如果hive處理的文件是壓縮模式,且壓縮模式不支持文件切分,那么這個(gè)時(shí)候我們只能通過(guò)控制參數(shù)來(lái)減少map個(gè)數(shù),而不能通過(guò)配置參數(shù)來(lái)增加map個(gè)數(shù),所以Hive對(duì)于壓縮不可切分文件的調(diào)優(yōu)有限

<2>如果Hive處理的的文件為非壓縮格式或者壓縮可切分,且inputFormat為CombineHiveInputFormat時(shí),

則控制map個(gè)數(shù)是由以下四個(gè)參數(shù)起作用,關(guān)于這四個(gè)參數(shù)作用優(yōu)先級(jí)與使用注意事項(xiàng)請(qǐng)參考如下:

一般來(lái)講這幾個(gè)參數(shù)的結(jié)果大小要滿足以下條件:

max.split.size >= min.split.size >= min.size.per.node >= min.size.per.rack

幾個(gè)參數(shù)的作用優(yōu)先級(jí)為:

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

總結(jié):所以對(duì)于控制map的個(gè)數(shù)進(jìn)行調(diào)優(yōu),首先需要看是否開(kāi)啟了壓縮,壓縮算法是否支持切分,參數(shù)的設(shè)置等等!

5、**set mapred.min.split.size.per.node=256000000;**

一個(gè)節(jié)點(diǎn)上split的至少的大小(這個(gè)值決定了多個(gè)DataNode上的文件是否需要合并) ,

和第3和第4個(gè)參數(shù)一起配合使用。

6、**set mapred.min.split.size.per.rack=256000000;**

一個(gè)交換機(jī)下split的至少的大小(這個(gè)值決定了多個(gè)交換機(jī)上的文件是否需要合并) ,

也適合第3,4,5的參數(shù)一起配合使用。

7、**set hive.exec.mode.local.auto=true;**

開(kāi)啟本地模式,這個(gè)參數(shù)在自己學(xué)習(xí)中可能經(jīng)常用到,但是在實(shí)際生產(chǎn)中用到的還是比較少,

因?yàn)檫@個(gè)參數(shù)開(kāi)啟后,針對(duì)的是小數(shù)據(jù)集,在單臺(tái)機(jī)器上處理所有的任務(wù),對(duì)生產(chǎn)中的任務(wù)不適用!

8、**set hive.exec.reducers.bytes.per.reducer=512*1000*1000;**

每個(gè)reduce任務(wù)處理的數(shù)據(jù)量,默認(rèn)為256M,在hive0.14.0之前默認(rèn)是1G,我們公司設(shè)置的是512M,寫(xiě)的是512*1000*1000因?yàn)樵诰W(wǎng)絡(luò)傳輸中用的是1000,而不是1024機(jī)制,

將該參數(shù)值調(diào)小可以增加reduce的數(shù)量,提高運(yùn)行的效率,

當(dāng)然也不是reduce的數(shù)量越多越好,因?yàn)閱?dòng)和初始化reduce都是會(huì)消耗資源和時(shí)間的,

而且有多少個(gè)reduce就會(huì)有多少個(gè)輸出文件,如果這些文件作為下一個(gè)任務(wù)的輸入,就會(huì)造成小文件過(guò)多的問(wèn)題

9、**hive.exec.reducers.max**

每個(gè)任務(wù)最大的reduce數(shù),默認(rèn)為1009,在hive0.14.0之前默認(rèn)是999

計(jì)算reducer數(shù)的公式很簡(jiǎn)單N=min(參數(shù)9,總輸入數(shù)據(jù)量/參數(shù)8)

即,如果reduce的輸入(map的輸出)總大小不超過(guò)1G,那么只會(huì)有一個(gè)reduce任務(wù);

10、**set mapred.reduce.tasks = 15;**

設(shè)置reduce的個(gè)數(shù)(在實(shí)際生產(chǎn)中謹(jǐn)慎使用)

那么什么時(shí)候可以進(jìn)行手動(dòng)設(shè)定reduce數(shù)量呢?比如系統(tǒng)自動(dòng)計(jì)算的reduce個(gè)數(shù),因?yàn)榧嘿Y源不足,

造成程序運(yùn)行出現(xiàn)OOM(內(nèi)存溢出不足)時(shí),可以根據(jù)推定的reduce個(gè)數(shù)手動(dòng)增加數(shù)量,保證程序在跑的慢的基礎(chǔ)上可以完整運(yùn)行

那么在什么情況下只有一個(gè)reduce呢?

<1>、當(dāng)map的輸出文件小于hive.exec.reducers.bytes.per.reducer時(shí)

<2>、手動(dòng)設(shè)置set mapred.reduce.tasks =1時(shí)

<3>、使用了order by時(shí)(全局排序會(huì)使用一個(gè)reduce去處理)

<4>、表關(guān)聯(lián)時(shí)出現(xiàn)笛卡爾積

<5>、單獨(dú)使用count時(shí),比如:select count(*) from tablename,

如果改寫(xiě)加入了group by配合使用就不會(huì)出現(xiàn)一個(gè)reduce,比如:select sign_date,count(*) from tablename group by sign_date;

11、**set mapred.job.reuse.jvm.num.tasks=10;**

用于避免小文件的場(chǎng)景或者task特別多的場(chǎng)景,這類(lèi)場(chǎng)景大多數(shù)執(zhí)行時(shí)間都很短,因?yàn)閔ive調(diào)起mapreduce任務(wù),JVM的啟動(dòng)過(guò)程會(huì)造成很大的開(kāi)銷(xiāo),尤其是job有成千上萬(wàn)個(gè)task任務(wù)時(shí),JVM重用可以使得JVM實(shí)例在同一個(gè)job中重新使用N次

12、**set hive.exec.dynamic.partition=true;**

表示開(kāi)啟動(dòng)態(tài)分區(qū)功能

13、**set hive.exec.dynamic.partition.mode=nonstrict;**

表示允許所有分區(qū)都是動(dòng)態(tài)的,

默認(rèn)是strict,表示必須保證至少有一個(gè)分區(qū)是靜態(tài)的

14、**set hive.groupby.skewindata=true;**

有數(shù)據(jù)傾斜的時(shí)候進(jìn)行負(fù)載均衡 ,決定group by操作是否支持傾斜數(shù)據(jù),其實(shí)說(shuō)白了就相當(dāng)于MR中的conbiner做了一次預(yù)聚合。

注意:只能對(duì)單個(gè)字段聚合。

控制生成兩個(gè)MR Job,第一個(gè)MR Job Map的輸出結(jié)果隨機(jī)分配到reduce中減少某些key值條數(shù)過(guò)多某些key條數(shù)過(guò)小造成的數(shù)據(jù)傾斜問(wèn)題。

在第一個(gè) MapReduce 中,map 的輸出結(jié)果集合會(huì)隨機(jī)分布到 reduce 中, 每個(gè)reduce 做部分聚合操作,并輸出結(jié)果。這樣處理的結(jié)果是,相同的 Group By Key 有可能分發(fā)到不同的reduce中,從而達(dá)到負(fù)載均衡的目的;

第二個(gè) MapReduce 任務(wù)再根據(jù)預(yù)處理的數(shù)據(jù)結(jié)果按照 Group By Key 分布到 reduce 中(這個(gè)過(guò)程可以保證相同的 Group By Key 分布到同一個(gè) reduce 中),最后完成最終的聚合操作

15、**set hive.auto.convert.join=true;**

開(kāi)啟map join

16、**set hive.mapjoin.smalltable.filesize=512000000;**

map join的小表的大小,也是開(kāi)啟和關(guān)閉map join的閾值

17、**hive.exec.compress.output=true;**

開(kāi)啟壓縮,我們公司使用的是默認(rèn)的壓縮算法deflate

壓縮算法有:<1>、org.apache.hadoop.io.compress.GzipCodec,

? <2>、org.apache.hadoop.io.compress.DefaultCodec,

? <3>、com.hadoop.compression.lzo.LzoCodec,

? <4>、com.hadoop.compression.lzo.LzopCodec,

? <5>、org.apache.hadoop.io.compress.BZip2Codec

使用的壓縮算法:

set mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.DefaultCodec

**針對(duì)上述小文件合并的三個(gè)參數(shù)值做以下解釋?zhuān)?*

大于文件塊大小128m的,按照128m來(lái)分隔,小于128m,大于100m的,按照100m來(lái)分隔,把那些小于100m的(包括小文件和分隔大文件剩下的),進(jìn)行合并

?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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