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
查看文件大小和文件數:
[dwapp@dw-yuntigw-63 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
文件: | 大小Bytes | 大小MB | splitsize(MB) | 每個文件需要的map數量 | |
文件1 | 290700555 | 277.2336531 | 256 | 1.082943957 | |
文件2 | 290695945 | 277.2292566 | 256 | 1.082926784 | |
文件3 | 290182606 | 276.7396984 | 256 | 1.081014447 | |
文件4 | 271979933 | 259.3802767 | 256 | 1.013204206 | |
文件5 | 258448208 | 246.4754181 | 256 | 0.962794602 | |
文件6 | 258440338 | 246.4679127 | 256 | 0.962765284 | |
文件7 | 258419852 | 246.4483757 | 256 | 0.962688968 | |
文件8 | 258347423 | 246.379302 | 256 | 0.962419149 | |
文件9 | 258349480 | 246.3812637 | 256 | 0.962426811 | |
文件10 | 258301657 | 246.3356562 | 256 | 0.962248657 | |
文件11 | 258270954 | 246.3063755 | 256 | 0.962134279 | |
文件12 | 258266805 | 246.3024187 | 256 | 0.962118823 | |
文件13 | 258253133 | 246.2893801 | 256 | 0.962067891 | |
文件14 | 258236047 | 246.2730856 | 256 | 0.962004241 | |
文件15 | 258239072 | 246.2759705 | 256 | 0.96201551 | |
文件16 | 258170671 | 246.2107382 | 256 | 0.961760696 | |
文件17 | 258160711 | 246.2012396 | 256 | 0.961723592 | |
文件18 | 258085783 | 246.1297827 | 256 | 0.961444464 | |
總文件大小: | 4759549173 | 4539.059804 |
goalSize = 4539.059804 (文件總大小)/ mapred.map.tasks(2) = 2269.529902MB
因此splitsize取值爲256MB,所以一共分配18個map。
修改map.tasks參數爲32
set mapred.map.tasks = 32;
文件: | 大小Bytes | 大小MB | splitsize(MB) | 每個文件需要的map數量 | |
文件1 | 290700555 | 277.2336531 | 141.8 | 1.955103336 | |
文件2 | 290695945 | 277.2292566 | 141.8 | 1.955072332 | |
文件3 | 290182606 | 276.7396984 | 141.8 | 1.951619876 | |
文件4 | 271979933 | 259.3802767 | 141.8 | 1.829198002 | |
文件5 | 258448208 | 246.4754181 | 141.8 | 1.738190537 | |
文件6 | 258440338 | 246.4679127 | 141.8 | 1.738137607 | |
文件7 | 258419852 | 246.4483757 | 141.8 | 1.737999829 | |
文件8 | 258347423 | 246.379302 | 141.8 | 1.737512708 | |
文件9 | 258349480 | 246.3812637 | 141.8 | 1.737526543 | |
文件10 | 258301657 | 246.3356562 | 141.8 | 1.737204909 | |
文件11 | 258270954 | 246.3063755 | 141.8 | 1.736998417 | |
文件12 | 258266805 | 246.3024187 | 141.8 | 1.736970513 | |
文件13 | 258253133 | 246.2893801 | 141.8 | 1.736878562 | |
文件14 | 258236047 | 246.2730856 | 141.8 | 1.73676365 | |
文件15 | 258239072 | 246.2759705 | 141.8 | 1.736783995 | |
文件16 | 258170671 | 246.2107382 | 141.8 | 1.736323965 | |
文件17 | 258160711 | 246.2012396 | 141.8 | 1.736256979 | |
文件18 | 258085783 | 246.1297827 | 141.8 | 1.735753051 | |
總文件大小: | 4759549173 | 4539.059804 |
goalSize = 4539.059804 / mapred.map.tasks(32) = 141.8456189
因此splitsize取值爲141.8MB,所以一共分配36個map。
原文出處:http://blog.csdn.net/lpxuan151009/article/details/7937821