溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何控制hive中的map數(shù)

發(fā)布時間:2021-12-10 10:54:57 來源:億速云 閱讀:271 作者:小新 欄目:云計算

這篇文章給大家分享的是有關如何控制hive中的map數(shù)的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

1. 通常情況下,作業(yè)會通過input的目錄產(chǎn)生一個或者多個map任務。

主要的決定因素有: input的文件總個數(shù),input的文件大小,集群設置的文件塊大小(目前為128M, 可在hive中通過set dfs.block.size;命令查看到,該參數(shù)不能自定義修改);

2. 舉例:
a) 假設input目錄下有1個文件a,大小為780M,那么hadoop會將該文件a分隔成7個塊(6個128m的塊和1個12m的塊),從而產(chǎn)生7個map數(shù)
b) 假設input目錄下有3個文件a,b,c,大小分別為10m,20m,130m,那么hadoop會分隔成4個塊(10m,20m,128m,2m),從而產(chǎn)生4個map數(shù)
即,如果文件大于塊大小(128m),那么會拆分,如果小于塊大小,則把該文件當成一個塊。

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

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

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

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

我通過以下方法來在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í)行上面的語句,用了74個map任務,map消耗的計算資源:SLOTS_MILLIS_MAPS= 333,500
對于這個簡單SQL任務,執(zhí)行時間上可能差不多,但節(jié)省了一半的計算資源。
大概解釋一下,100000000表示100M, sethive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;這個參數(shù)表示執(zhí)行前進行小文件合并,
前面三個參數(shù)確定合并文件塊的大小,大于文件塊大小128m的,按照128m來分隔,小于128m,大于100m的,按照100m來分隔,把那些小于100m的(包括小文件和分隔大文件剩下的),
進行合并,最終生成了74個塊。

如何適當?shù)脑黾觤ap數(shù)?

當input的文件都很大,任務邏輯復雜,map執(zhí)行非常慢的時候,可以考慮增加Map數(shù),來使得每個map處理的數(shù)據(jù)量減少,從而提高任務的執(zhí)行效率。
假設有這樣一個任務:
Select data_desc,
count(1),
count(distinct id),
sum(case when …),
sum(case when ...),
sum(…)
from a group by data_desc
如果表a只有一個文件,大小為120M,但包含幾千萬的記錄,如果用1個map去完成這個任務,肯定是比較耗時的,這種情況下,我們要考慮將這一個文件合理的拆分成多個,
這樣就可以用多個map任務去完成。
set mapred.reduce.tasks=10;
create table a_1 as 
select * from a 
distribute by rand(123); 

這樣會將a表的記錄,隨機的分散到包含10個文件的a_1表中,再用a_1代替上面sql中的a表,則會用10個map任務去完成。
每個map任務處理大于12M(幾百萬記錄)的數(shù)據(jù),效率肯定會好很多。

看上去,貌似這兩種有些矛盾,一個是要合并小文件,一個是要把大文件拆成小文件,這點正是重點需要關注的地方,
根據(jù)實際情況,控制map數(shù)量需要遵循兩個原則:使大數(shù)據(jù)量利用合適的map數(shù);使單個map任務處理合適的數(shù)據(jù)量;

感謝各位的閱讀!關于“如何控制hive中的map數(shù)”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI