日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

hive優(yōu)化之------控制hive任務(wù)中的map數(shù)和reduc

系統(tǒng) 2847 0

一、??? 控制hive任務(wù)中的map數(shù):

1.??? 通常情況下,作業(yè)會(huì)通過(guò)input的目錄產(chǎn)生一個(gè)或者多個(gè)map任務(wù)。
主要的決定因素有: input的文件總個(gè)數(shù),input的文件大小,集群設(shè)置的文件塊大小(目前為128M, 可在hive中通過(guò)set dfs.block.size;命令查看到,該參數(shù)不能自定義修改);

2.??? 舉例:
a)??? 假設(shè)input目錄下有1個(gè)文件a,大小為780M,那么hadoop會(huì)將該文件a分隔成7個(gè)塊(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ù)
即,如果文件大于塊大小(128m),那么會(huì)拆分,如果小于塊大小,則把該文件當(dāng)成一個(gè)塊。

3.??? 是不是map數(shù)越多越好?
答案是否定的。如果一個(gè)任務(wù)有很多小文件(遠(yuǎn)遠(yuǎn)小于塊大小128m),則每個(gè)小文件也會(huì)被當(dāng)做一個(gè)塊,用一個(gè)map任務(wù)來(lái)完成,
而一個(gè)map任務(wù)啟動(dòng)和初始化的時(shí)間遠(yuǎn)遠(yuǎn)大于邏輯處理的時(shí)間,就會(huì)造成很大的資源浪費(fèi)。
而且,同時(shí)可執(zhí)行的map數(shù)是受限的。

?

4.??? 是不是保證每個(gè)map處理接近128m的文件塊,就高枕無(wú)憂了?
答案也是不一定。比如有一個(gè)127m的文件,正常會(huì)用一個(gè)map去完成,但這個(gè)文件只有一個(gè)或者兩個(gè)小字段,卻有幾千萬(wàn)的記錄,
如果map處理的邏輯比較復(fù)雜,用一個(gè)map任務(wù)去做,肯定也比較耗時(shí)。

針對(duì)上面的問(wèn)題3和4,我們需要采取兩種方式來(lái)解決:即減少map數(shù)和增加map數(shù);

如何合并小文件,減少map數(shù)?
??? 假設(shè)一個(gè)SQL任務(wù):
???????? Select count(1) from popt_tbaccountcopy_mes where pt = ‘2012-07-04’;
???????? 該任務(wù)的inputdir? /group/p_sdo_data/p_sdo_data_etl/pt/popt_tbaccountcopy_mes/pt=2012-07-04
???????? 共有194個(gè)文件,其中很多是遠(yuǎn)遠(yuǎn)小于128m的小文件,總大小9G,正常執(zhí)行會(huì)用194個(gè)map任務(wù)。
???????? Map總共消耗的計(jì)算資源: SLOTS_MILLIS_MAPS= 623,020

???????? 我通過(guò)以下方法來(lái)在map執(zhí)行前合并小文件,減少map數(shù):
???????? set mapred.max.split.size=100000000;
??? ??? ??? ??? ??? set mapred.min.split.size.per.node=100000000;
??? ??? ??? ??? ??? set mapred.min.split.size.per.rack=100000000;
??? ??? ??? ??? ??? set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
??? ??? ??? ??? ?再執(zhí)行上面的語(yǔ)句,用了74個(gè)map任務(wù),map消耗的計(jì)算資源:SLOTS_MILLIS_MAPS= 333,500
???????? 對(duì)于這個(gè)簡(jiǎn)單SQL任務(wù),執(zhí)行時(shí)間上可能差不多,但節(jié)省了一半的計(jì)算資源。
???????? 大概解釋一下,100000000表示100M, set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;這個(gè)參數(shù)表示執(zhí)行前進(jìn)行小文件合并,
???????? 前面三個(gè)參數(shù)確定合并文件塊的大小,大于文件塊大小128m的,按照128m來(lái)分隔,小于128m,大于100m的,按照100m來(lái)分隔,把那些小于100m的(包括小文件和分隔大文件剩下的),
???????? 進(jìn)行合并,最終生成了74個(gè)塊。
????????
如何適當(dāng)?shù)脑黾觤ap數(shù)?

???????? 當(dāng)input的文件都很大,任務(wù)邏輯復(fù)雜,map執(zhí)行非常慢的時(shí)候,可以考慮增加Map數(shù),來(lái)使得每個(gè)map處理的數(shù)據(jù)量減少,從而提高任務(wù)的執(zhí)行效率。
???????? 假設(shè)有這樣一個(gè)任務(wù):
???????? Select data_desc,
??? ??? ??? ??? count(1),
??? ??? ??? ??? count(distinct id),
??? ??? ??? ??? sum(case when …),
??? ??? ??? ??? sum(case when ...),
??? ??? ??? ??? sum(…)
??????? from a group by data_desc
?????????????????? 如果表a只有一個(gè)文件,大小為120M,但包含幾千萬(wàn)的記錄,如果用1個(gè)map去完成這個(gè)任務(wù),肯定是比較耗時(shí)的,這種情況下,我們要考慮將這一個(gè)文件合理的拆分成多個(gè),
?????????????????? 這樣就可以用多個(gè)map任務(wù)去完成。
?????????????????? set mapred.reduce.tasks=10;
?????????????????? create table a_1 as
?????????????????? select * from a
?????????????????? distribute by rand(123);
??????????????????
?????????????????? 這樣會(huì)將a表的記錄,隨機(jī)的分散到包含10個(gè)文件的a_1表中,再用a_1代替上面sql中的a表,則會(huì)用10個(gè)map任務(wù)去完成。
?????????????????? 每個(gè)map任務(wù)處理大于12M(幾百萬(wàn)記錄)的數(shù)據(jù),效率肯定會(huì)好很多。
???
?? 看上去,貌似這兩種有些矛盾,一個(gè)是要合并小文件,一個(gè)是要把大文件拆成小文件,這點(diǎn)正是重點(diǎn)需要關(guān)注的地方,
?? 根據(jù)實(shí)際情況,控制map數(shù)量需要遵循兩個(gè)原則:使大數(shù)據(jù)量利用合適的map數(shù);使單個(gè)map任務(wù)處理合適的數(shù)據(jù)量;

?

二、??? 控制hive任務(wù)的reduce數(shù):

1.??? Hive自己如何確定reduce數(shù):
reduce個(gè)數(shù)的設(shè)定極大影響任務(wù)執(zhí)行效率,不指定reduce個(gè)數(shù)的情況下,Hive會(huì)猜測(cè)確定一個(gè)reduce個(gè)數(shù),基于以下兩個(gè)設(shè)定:
hive.exec.reducers.bytes.per.reducer(每個(gè)reduce任務(wù)處理的數(shù)據(jù)量,默認(rèn)為1000^3=1G)
hive.exec.reducers.max(每個(gè)任務(wù)最大的reduce數(shù),默認(rèn)為999)
計(jì)算reducer數(shù)的公式很簡(jiǎn)單N=min(參數(shù)2,總輸入數(shù)據(jù)量/參數(shù)1)
即,如果reduce的輸入(map的輸出)總大小不超過(guò)1G,那么只會(huì)有一個(gè)reduce任務(wù);
如: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個(gè)reduce

2.??? 調(diào)整reduce個(gè)數(shù)方法一:
調(diào)整hive.exec.reducers.bytes.per.reducer參數(shù)的值;
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個(gè)reduce
????????
3.??? 調(diào)整reduce個(gè)數(shù)方法二;
set mapred.reduce.tasks = 15;
select pt,count(1) from popt_tbaccountcopy_mes where pt = '2012-07-04' group by pt;這次有15個(gè)reduce

4.??? reduce個(gè)數(shù)并不是越多越好;
同map一樣,啟動(dòng)和初始化reduce也會(huì)消耗時(shí)間和資源;
另外,有多少個(gè)reduce,就會(huì)有多少個(gè)輸出文件,如果生成了很多個(gè)小文件,那么如果這些小文件作為下一個(gè)任務(wù)的輸入,則也會(huì)出現(xiàn)小文件過(guò)多的問(wèn)題;

5.??? 什么情況下只有一個(gè)reduce;
很多時(shí)候你會(huì)發(fā)現(xiàn)任務(wù)中不管數(shù)據(jù)量多大,不管你有沒(méi)有設(shè)置調(diào)整reduce個(gè)數(shù)的參數(shù),任務(wù)中一直都只有一個(gè)reduce任務(wù);
其實(shí)只有一個(gè)reduce任務(wù)的情況,除了數(shù)據(jù)量小于hive.exec.reducers.bytes.per.reducer參數(shù)值的情況外,還有以下原因:
a)??? 沒(méi)有g(shù)roup 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';
這點(diǎn)非常常見,希望大家盡量改寫。
b)??? 用了Order by
c)??? 有笛卡爾積
通常這些情況下,除了找辦法來(lái)變通和避免,我暫時(shí)沒(méi)有什么好的辦法,因?yàn)檫@些操作都是全局的,所以hadoop不得不用一個(gè)reduce去完成;

??? 同樣的,在設(shè)置reduce個(gè)數(shù)的時(shí)候也需要考慮這兩個(gè)原則:使大數(shù)據(jù)量利用合適的reduce數(shù);使單個(gè)reduce任務(wù)處理合適的數(shù)據(jù)量;

hive優(yōu)化之------控制hive任務(wù)中的map數(shù)和reduce數(shù)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 乌兰浩特市| 新安县| 正安县| 汝城县| 那曲县| 阿勒泰市| 大同市| 阜新| 日照市| 友谊县| 玉树县| 城口县| 邵东县| 广宗县| 大竹县| 左云县| 达州市| 东乡族自治县| 竹溪县| 澜沧| 铜山县| 凌云县| 三都| 珠海市| 黄龙县| 永济市| 南通市| 抚松县| 淅川县| 邹平县| 沂南县| 长岭县| 策勒县| 平谷区| 府谷县| 青州市| 新巴尔虎左旗| 黄冈市| 隆尧县| 毕节市| 建瓯市|