Mapreduce和Hive中map reduce个数设定.doc

上传人:白大夫 文档编号:3255889 上传时间:2019-08-06 格式:DOC 页数:7 大小:29.50KB
返回 下载 相关 举报
Mapreduce和Hive中map reduce个数设定.doc_第1页
第1页 / 共7页
亲,该文档总共7页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《Mapreduce和Hive中map reduce个数设定.doc》由会员分享,可在线阅读,更多相关《Mapreduce和Hive中map reduce个数设定.doc(7页珍藏版)》请在三一文库上搜索。

1、Mapreduce和Hive中map reduce个数设定Mapreduce中mapper个数的确定1)Mapreduce中mapper个数的确定: 在map阶段读取数据前,FileInputFormat会将输入文件分割成split。split的个数决定了map的个数。 影响map个数,即split个数的因素主要有: 1)HDFS块的大小,即HDFS中dfs.block.size的值。如果有一个输入文件为1024m,当块为256m时,会被划分为4个split;当块为128m时,会被划分为8个split。2)文件的大小。当块为128m时,如果输入文件为128m,会被划分为1个split;当块为2

2、56m,会被划分为2个split。3)文件的个数。FileInputFormat按照文件分割split,并且只会分割大文件,即那些大小超过HDFS块的大小的文件。如果HDFS中dfs.block.size设置为64m,而输入的目录中文件有100个,则划分后的split个数至少为100个。4)splitsize的大小。分片是按照splitszie的大小进行分割的,一个split的大小在没有设置的情况下,默认等于hdfs block的大小。但应用程序可以通过两个参数来对splitsize进行调节。 Mapper个数的计算如下:Step1,splitsize=max(minimumsize,min(

3、maximumsize,blocksize)。 如果没有设置minimumsize和maximumsize,splitsize的大小默认等于blocksizeStep2,计算过程可以简化为如下的公式,详细算法可以参照FileInputSplit类中的getSplits方法total_split for(file :输入目录中的每个文件) file_split = 1;if(file.sizesplitsize) file_split=file_size/splitsize;total_split+=file_split; Mapreduce中Reducer个数确定:1,在缺省情况下,一个map

4、reduce的job只有一个reducer;在大型集群中,需要使用许多reducer,中间数据都会放到一个reducer中处理,如果reducer数量不够,会成为计算瓶颈。 2,reducer的最优个数与集群中可用的reducer的任务槽数相关,一般设置比总槽数稍微少一些的reducer数量;Hadoop文档中推荐了两个公式: 0.95*NUMBER_OF_NODES*mapred.tasktracker.reduce.tasks.maximum 1.75*NUMBER_OF_NODES*mapred.tasktracker.reduce.tasks.maximum备注:NUMBER_OF_N

5、ODES是集群中的计算节点个数; mapred.tasktracker.reduce.tasks.maximum:每个节点所分配的reducer任务槽的个数(节点内核数);2,在代码中通过:JobConf.setNumReduceTasks(Int numOfReduceTasks)方法设置reducer的个数;Hive job相关参数配置和mapreduce数目控制在 hiveconfhive_site.xml中配置如下性能调优项:开启动态分区: hive.exec.dynamic.parTITIon=true默认值:false描述:是否允许动态分区 hive.exec.dynamic.pa

6、rTITIon.mode=nonstrict默认值:strict描述:strict是避免全分区字段是动态的,必须有至少一个分区字段是指定有值的。读取表的时候可以不指定分区。 hive.exec.max.dynamic.partitions.pernode=100默认值:100描述:each mapper or reducer可以创建的最大动态分区数 hive.exec.max.dynamic.partitions=1000默认值:1000描述:一个DML操作可以创建的最大动态分区数 hive.exec.max.created.files=100000 默认值:100000描述:一个DML操作可

7、以创建的文件数 设置如下参数取消一些限制(HIVE 0.7后没有此限制): hive.merge.mapfiles=false默认值:true描述:是否合并Map的输出文件,也就是把小文件合并成一个map hive.merge.mapredfiles=false默认值:false描述:是否合并Reduce的输出文件,也就是在Map输出阶段做一次reduce操作,再输出 hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; 表示执行前进行小文件合并 配置如下参数,可以开启Hive的本地模式: hive.exe

8、c.mode.local.auto=true;(默认为false) 自0.7版本后Hive开始支持任务执行选择本地模式(local mode),如此一来,对数据量比较小的操作,就可以在本地执行,这样要比提交任务到集群执行效率要快很多。mapred.reduce.tasks; 设置当前Session的map,reduce 的个数,默认值是-1,为系统自动匹配。一、控制hive任务中的map数:1. 通常情况下,作业会通过input的目录产生一个或者多个map任务。 主要的决定因素有: input的文件总个数,input的文件大小,集群设置的文件块大小(hadoophdfs_site.xml中df

9、s.block.size的值;在HIVE中用set dfs.block.size命令查看到,该参数在HIVE中不能自定义修改);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数越多越好? 答案是否定的。如果一

10、个任务有很多小文件(远远小于块大小128m),则每个小文件也会被当做一个块,用一个map任务来完成, 而一个map任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。而且,同时可执行的map数是受限的。4.是不是保证每个map处理接近128m的文件块,就高枕无忧了?答案也是不一定。比如有一个127m的文件,正常会用一个map去完成, 但这个文件只有一个或者两个小字段,却有几千万的记录, 如果map处理的逻辑比较复杂,用一个map任务去做,肯定也比较耗时。针对上面的问题3和4,我们需要采取两种方式来解决:即减少map数和增加map数;如何合并小文件,减少map数?假设一个SQL

11、任务: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,正常执行会用194个map任务。Map总共消耗的计算资源: SLOTS_MILLIS_MAPS= 623,020通过以下方法来在map执行前合并小文件,减少map数:set mapred.max.split.size=10000

12、0000;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;再执行上面的语句,用了74个map任务,map消耗的计算资源:SLOTS_MILLIS_MAPS= 333,500对于这个简单SQL任务,执行时间上可能差不多,但节省了一半的计算资源。 大概解释一下,100000000表示100M,set hive.input.

13、format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;这个参数表示执行前进行小文件合并。 前面三个参数确定合并文件块的大小,大于文件块大小128m的,按照128m来分隔,小于128m,大于100m的,按照100m来分隔,把那些小于100m的(包括小文件和分隔大文件剩下的),进行合并,最终生成了74个块。 如何适当的增加map数? 当input的文件都很大,任务逻辑复杂,map执行非常慢的时候,可以考虑增加Map数, 来使得每个map处理的数据量减少,从而提高任务的执行效率。 假设有这样一个任务:Select data_desc,c

14、ount(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

15、个文件的a_1表中,再用a_1代替上面sql中的a表,则会用10个map任务去完成。 每个map任务处理大于12M(几百万记录)的数据,效率肯定会好很多。 看上去,貌似这两种有些矛盾,一个是要合并小文件,一个是要把大文件拆成小文件,这点正是重点需要关注的地方, 根据实际情况,控制map数量需要遵循两个原则:使大数据量利用合适的map数;使单个map任务处理合适的数据量;二、控制hive任务的reduce数:1. Hive自己如何确定reduce数:reduce个数的设定极大影响任务执行效率,不指定reduce个数的情况下(mapred.reduce.tasks = -1),Hive会猜测确定一

16、个reduce个数,基于以下两个设定: hive.exec.reducers.bytes.per.reducer(每个reduce任务处理的数据量,默认为1000=1G) hive.exec.reducers.max(每个任务最大的reduce数,默认为999) 计算reducer数的公式很简单N=min(参数2,总输入数据量/参数1) 即,如果reduce的输入(map的输出)总大小不超过1G,那么只会有一个reduce任务;如: select pt,count(1) from popt_tbaccountcopy_mes where pt = 2012-07-04 group by pt;

17、 /group/p_sdo_data/p_sdo_data_etl/pt/popt_tbaccountcopy_mes/pt=2012-07-04 总大小为9G多, 因此这句有10个reduce2. 调整reduce个数方法一:调整hive.exec.reducers.bytes.per.reducer参数的值;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; 这次

18、有20个reduce 3.调整reduce个数方法二:set mapred.reduce.tasks = 15; select pt,count(1) from popt_tbaccountcopy_mes where pt = 2012-07-04 group by pt;这次有15个reduce3. reduce个数并不是越多越好; 同map一样,启动和初始化reduce也会消耗时间和资源; 另外,有多少个reduce,就会有多少个输出文件,如果生成了很多个小文件, 那么如果这些小文件作为下一个任务的输入,则也会出现小文件过多的问题;什么情况下只有一个reduce?很多时候你会发现任务中不

19、管数据量多大,不管你有没有设置调整reduce个数的参数,任务中一直都只有一个reduce任务; 其实只有一个reduce任务的情况,除了数据量小于hive.exec.reducers.bytes.per.reducer参数值的情况外,还有以下原因:a) 没有group 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;b)用了O

20、rder by有笛卡尔积通常这些情况下,除了找办法来变通和避免,我暂时没有什么好的办法, 因为这些操作都是全局的,所以hadoop不得不用一个reduce去完成;同样的,在设置reduce个数的时候也需要考虑这两个原则: 使大数据量利用合适的reduce数;使单个reduce任务处理合适的数据量。 hive.exec.parallel参数控制在同一个sql中的不同的job是否可以同时运行,默认为false.下面是对于该参数的测试过程:测试sql: select r1.a from ( select t.a from sunwg_10 t join sunwg_10000000 s on t.a

21、=s.b) r1 join (select s.b from sunwg_100000 t join sunwg_10 s on t.a=s.b) r2 on (r1.a=r2.b);当参数为false的时候,三个job是顺序的执行 set hive.exec.parallel=false, 但是可以看出来其实两个子查询中的sql并无关系,可以并行的跑 set hive.exec.parallel=true; 总结: 在资源充足的时候hive.exec.parallel会让那些存在并发job的sql运行得更快,但同时消耗更多的资源可以评估下hive.exec.parallel对我们的刷新任务是否有帮助。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1