1. 程式人生 > >hive優化,控制map、reduce數量

hive優化,控制map、reduce數量

行合並 答案 只有一個 mapred hdfs yarn str 浪費 邏輯

一、調整hive作業中的map數

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

2.舉例:

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

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

4.是不是保證每個map處理接近128m的文件塊,就高枕無憂了?
答案也是不一定。比如有一個127m的文件,正常會用一個map去完成,但這個文件只有一個或者兩個小字段,卻有幾千萬的記錄,如果map處理的邏輯比較復雜,用一個map任務去做,肯定也比較耗時我通過以下方法來在map執行前合並小文件,減少map數:

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;

增加map數方法:

1、可以合理調整以下參數可以達到增加map數目的:

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;

2、重建目標表將物理分區切分成多份,如下:

create table emp002 as select * from emp distribute by rand(10);

二、調整hive作業中的reduce任務個數

1、調整reduce任務個數方法一:

設置參數:

set hive.exec.reducers.bytes.per.reducer=1000000000;

set hive.exec.reducers.max=999;

2、設置reduce任務個數方法二:

調整參數:

set mapred.reduce.tasks=10;

三、hive合並輸入輸出文件

如果Hive的輸入文件是大量的小文件,而每個文件啟動一個map的話是對yarn資源的浪費,同樣的,hive輸出的文件也遠遠小於HDFS塊大小,對後續處理也是不利的。

HIVE中支持通過參數調整輸入和輸出的文件大小

1、合並輸入文件

set mapred.max.split.size=256000000; #每個Map最大輸入大小
set mapred.min.split.size.per.node=100000000; #一個節點上split的至少的大小
set mapred.min.split.size.per.rack=100000000; #一個交換機下split的至少的大小
set hive.input.format=org.apache.Hadoop.hive.ql.io.CombineHiveInputFormat; #執行Map前進行小文件合並

開啟org.apache.hadoop.hive.ql.io.CombineHiveInputFormat後,一個data node節點上多個小文件會進行合並,合並文件數由mapred.max.split.size限制的大小決定,mapred.min.split.size.per.node決定了多個data node上的文件是否需要合並,mapred.min.split.size.per.rack決定了多個交換機上的文件是否需要合並。

2、合並輸出文件

set hive.merge.mapfiles = true #在Map-only的任務結束時合並小文件
set hive.merge.mapredfiles = true #在Map-Reduce的任務結束時合並小文件
set hive.merge.size.per.task = 256*1000*1000 #合並文件的大小
set hive.merge.smallfiles.avgsize=16000000 #當輸出文件的平均大小小於該值時,啟動一個獨立的map-reduce任務進行文件merge。

以上參數在hive-0.13.1中默認值如下:

hive (default)> set hive.merge.mapfiles;

hive.merge.mapfiles=true

hive (default)> set hive.merge.mapredfiles;

hive.merge.mapredfiles=false

hive (default)> set hive.merge.size.per.task;

hive.merge.size.per.task=256000000

hive (default)> set hive.merge.smallfiles.avgsize;

hive.merge.smallfiles.avgsize=16000000

綜上所述:一個可能的hive 作業可以設置為以下格式:

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;

set hive.exec.reducers.bytes.per.reducer=1000000000;

set hive.exec.reducers.max=256;

set hive.merge.mapfiles=true;

set hive.merge.mapredfiles =ture;

set hive.merge.size.per.task=256000000;

set hive.merge.smallfiles.avgsize=16000000;

select deptno,count(1) from emp group by deptno;

或者

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;

set mapred.reduce.tasks=10;

set hive.merge.mapfiles=true;

set hive.merge.mapredfiles =ture;

set hive.merge.size.per.task=256000000;

set hive.merge.smallfiles.avgsize=16000000;

select deptno,count(1) from emp group by deptno;

hive優化,控制map、reduce數量