記錄一下自己在工作中經(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)行合并