天天看點

Hadoop如何計算map數和reduce數首先分析一下job的maptask數下面來分析reducetask數在HIVE中運作sql的情況又不同總結:map資料計算示例:

Hadoop在運作一個mapreduce job之前,需要估算這個job的maptask數和reducetask數。

首先分析一下job的maptask數

當一個job送出時,jobclient首先分析job被拆分的split數量,然後吧job.split檔案放置在HDFS中,一個job的MapTask數量就等于split的個數。

job.split中包含split的個數由FileInputFormat.getSplits計算出,方法的邏輯如下:

1. 讀取參數mapred.map.tasks,這個參數預設設定為0,生産系統中很少修改。

2. 計算input檔案的總位元組數,總位元組數/(mapred.map.tasks==0 ? 1: mapred.map.tasks )=goalsize

3. 每個split的最小值minSize由mapred.min.split.size參數設定,這個參數預設設定為0,生産系統中很少修改。

4. 調用computeSplitSize方法,計算出splitsize= Math.max(minSize, Math.min(goalSize, blockSize)),通常這個值=blockSize,輸入的檔案較小,檔案位元組數之和小于blocksize時,splitsize=輸入檔案位元組數之和。

5. 對于input的每個檔案,計算split的個數。

      a) 檔案大小/splitsize>1.1,建立一個split,這個split的位元組數=splitsize,檔案剩餘位元組數=檔案大小-splitsize

      b) 檔案剩餘位元組數/splitsize<1.1,剩餘的部分作為一個split

舉例說明:

1. input隻有一個檔案,大小為100M,splitsize=blocksize,則split數為2,第一個split為64M,第二個為36M

2. input隻有一個檔案,大小為65M,splitsize=blocksize,則split數為1,split大小為65M

3. input隻有一個檔案,大小為129M,splitsize=blocksize,則split數為2,第一個split為64M,第二個為65M(最後一個split的大小可能超過splitsize)

4. input隻有一個檔案,大小為20M ,splitsize=blocksize,則split數為1,split大小為20M

5. input有兩個檔案,大小為100M和20M,splitsize=blocksize,則split數為3,第一個檔案分為兩個split,第一個split為64M,第二個為36M,第二個檔案為一個split,大小為20M

6. input有兩個檔案,大小為25M和20M,splitsize=blocksize,則split數為2,第一個檔案為一個split,大小為25M,第二個檔案為一個split,大小為20M

     假設一個job的input大小固定為100M,當隻包含一個檔案時,split個數為2,maptask數為2,但當包含10個10M的檔案時,maptask數為10。

下面來分析reducetask數

純粹的mapreduce task的reduce task數很簡單,就是參數mapred.reduce.tasks的值,hadoop-site.xml檔案中和mapreduce job運作時不設定的話預設為1。

在HIVE中運作sql的情況又不同

hive會估算reduce task的數量,估算方法如下:

通常是ceil(input檔案大小/1024*1024*1024),每1GB大小的輸入檔案對應一個reduce task。

特殊的情況是當sql隻查詢count(*)時,reduce task數被設定成1。

總結:

通過map和reducetask數量的分析可以看出,hadoop/hive估算的map和reduce task數可能和實際情況相差甚遠。假定某個job的input資料量龐大,reduce task數量也會随之變大,而通過join和group by,實際output的資料可能不多,但reduce會輸出大量的小檔案,這個job的下遊任務将會啟動同樣多的map來處理前面reduce産生的大量檔案。在生産環境中每個user group有一個map task數的限額,一個job啟動大量的map task很顯然會造成其他job等待釋放資源。

Hive對于上面描述的情況有一種補救措施,參數hive.merge.smallfiles.avgsize控制hive對output小檔案的合并,當hiveoutput的檔案的平均大小小于hive.merge.smallfiles.avgsize-預設為16MB左右,hive啟動一個附加的mapreducejob合并小檔案,合并後檔案大小不超過hive.merge.size.per.task-預設為256MB。

盡管Hive可以啟動小檔案合并的過程,但會消耗掉額外的計算資源,控制單個reduce task的輸出大小>64MB才是最好的解決辦法。

map資料計算示例:

hive> set dfs.block.size;

dfs.block.size=268435456

hive> set mapred.map.tasks;

mapred.map.tasks=2

檔案塊大小為256MB,map.tasks為2

檢視檔案大小和檔案數:

[[email protected] hadoop]$ hadoop dfs -ls /group/alibaba-dw-icbu/hive/bdl_en12_pageview_fatdt0_d/hp_stat_date=2012-11-25;

Found 18 items

-rw-r----- 3 alidwicbu cug-alibaba-dw-icbu 290700555 2012-11-26 19:00 /group/alibaba-dw-icbu/hive/bdl_en12_pageview_fatdt0_d/hp_stat_date=2012-11-25/attempt_201211151327_1675393_m_000000_0

-rw-r----- 3 alidwicbu cug-alibaba-dw-icbu 290695945 2012-11-26 18:59 /group/alibaba-dw-icbu/hive/bdl_en12_pageview_fatdt0_d/hp_stat_date=2012-11-25/attempt_201211151327_1675393_m_000001_0

-rw-r----- 3 alidwicbu cug-alibaba-dw-icbu 290182606 2012-11-26 19:00 /group/alibaba-dw-icbu/hive/bdl_en12_pageview_fatdt0_d/hp_stat_date=2012-11-25/attempt_201211151327_1675393_m_000002_0

-rw-r----- 3 alidwicbu cug-alibaba-dw-icbu 271979933 2012-11-26 19:00 /group/alibaba-dw-icbu/hive/bdl_en12_pageview_fatdt0_d/hp_stat_date=2012-11-25/attempt_201211151327_1675393_m_000003_0

-rw-r----- 3 alidwicbu cug-alibaba-dw-icbu 258448208 2012-11-26 18:59 /group/alibaba-dw-icbu/hive/bdl_en12_pageview_fatdt0_d/hp_stat_date=2012-11-25/attempt_201211151327_1675393_m_000004_0

-rw-r----- 3 alidwicbu cug-alibaba-dw-icbu 258440338 2012-11-26 18:59 /group/alibaba-dw-icbu/hive/bdl_en12_pageview_fatdt0_d/hp_stat_date=2012-11-25/attempt_201211151327_1675393_m_000005_0

-rw-r----- 3 alidwicbu cug-alibaba-dw-icbu 258419852 2012-11-26 18:59 /group/alibaba-dw-icbu/hive/bdl_en12_pageview_fatdt0_d/hp_stat_date=2012-11-25/attempt_201211151327_1675393_m_000006_0

-rw-r----- 3 alidwicbu cug-alibaba-dw-icbu 258347423 2012-11-26 18:59 /group/alibaba-dw-icbu/hive/bdl_en12_pageview_fatdt0_d/hp_stat_date=2012-11-25/attempt_201211151327_1675393_m_000007_0

-rw-r----- 3 alidwicbu cug-alibaba-dw-icbu 258349480 2012-11-26 18:59 /group/alibaba-dw-icbu/hive/bdl_en12_pageview_fatdt0_d/hp_stat_date=2012-11-25/attempt_201211151327_1675393_m_000008_0

-rw-r----- 3 alidwicbu cug-alibaba-dw-icbu 258301657 2012-11-26 18:59 /group/alibaba-dw-icbu/hive/bdl_en12_pageview_fatdt0_d/hp_stat_date=2012-11-25/attempt_201211151327_1675393_m_000009_0

-rw-r----- 3 alidwicbu cug-alibaba-dw-icbu 258270954 2012-11-26 18:59 /group/alibaba-dw-icbu/hive/bdl_en12_pageview_fatdt0_d/hp_stat_date=2012-11-25/attempt_201211151327_1675393_m_000010_0

-rw-r----- 3 alidwicbu cug-alibaba-dw-icbu 258266805 2012-11-26 18:59 /group/alibaba-dw-icbu/hive/bdl_en12_pageview_fatdt0_d/hp_stat_date=2012-11-25/attempt_201211151327_1675393_m_000011_0

-rw-r----- 3 alidwicbu cug-alibaba-dw-icbu 258253133 2012-11-26 18:59 /group/alibaba-dw-icbu/hive/bdl_en12_pageview_fatdt0_d/hp_stat_date=2012-11-25/attempt_201211151327_1675393_m_000012_0

-rw-r----- 3 alidwicbu cug-alibaba-dw-icbu 258236047 2012-11-26 18:59 /group/alibaba-dw-icbu/hive/bdl_en12_pageview_fatdt0_d/hp_stat_date=2012-11-25/attempt_201211151327_1675393_m_000013_0

-rw-r----- 3 alidwicbu cug-alibaba-dw-icbu 258239072 2012-11-26 18:59 /group/alibaba-dw-icbu/hive/bdl_en12_pageview_fatdt0_d/hp_stat_date=2012-11-25/attempt_201211151327_1675393_m_000014_0

-rw-r----- 3 alidwicbu cug-alibaba-dw-icbu 258170671 2012-11-26 19:00 /group/alibaba-dw-icbu/hive/bdl_en12_pageview_fatdt0_d/hp_stat_date=2012-11-25/attempt_201211151327_1675393_m_000015_0

-rw-r----- 3 alidwicbu cug-alibaba-dw-icbu 258160711 2012-11-26 18:59 /group/alibaba-dw-icbu/hive/bdl_en12_pageview_fatdt0_d/hp_stat_date=2012-11-25/attempt_201211151327_1675393_m_000016_0

-rw-r----- 3 alidwicbu cug-alibaba-dw-icbu 258085783 2012-11-26 18:59 /group/alibaba-dw-icbu/hive/bdl_en12_pageview_fatdt0_d/hp_stat_date=2012-11-25/attempt_201211151327_1675393_m_000017_0

goalSize = 4539.059804 (檔案總大小)/ mapred.map.tasks(2) = 2269.529902MB

是以splitsize取值為256MB,是以一共配置設定18個map。

修改map.tasks參數為32

set mapred.map.tasks = 32;

goalSize = 4539.059804 / mapred.map.tasks(32) = 141.8456189

是以splitsize取值為141.8MB,是以一共配置設定36個map。

繼續閱讀