Hive参数层面优化之一控制Map数

1、Map个数的决定因素

通常情况下,作业会通过input文件产生一个或者多个map数;

Map数主要的决定因素有: input总的文件个数,input文件的大小和集群中设置的block的大小(在hive中可以通过set dfs.block.size命令查看,该参数不能自定义修改);

文件块数拆分原则:如果文件大于块大小(128M),那么拆分;如果小于,则把该文件当成一个块

举例一:

假设input目录下有1个文件a,大小为780M,那么hadoop会将该文件a分隔成7个块(6个128m的块和1个12m的块,Block是128M),从而产生7个map数;

实例二:

假设input目录下有3个文件a,b,c,大小分别为10m,20m,130m,那么hadoop会分隔成4个块(10m,20m,128m,2m),从而产生4个map数;

两种方式控制Map数:即减少map数和增加map

减少map数可以通过合并小文件来实现,针对文件源;

增加map数的可以通过控制上一个job的reduer数来控制(一个sql中join多个表会分解为多个mapreduce),因为上一个job的reduce输出数决定了这个job的map数;

2、Map数过大或过小引发的问题

Map数过大将导致:

1)  Map阶段输出文件太小,产生大量小文件;当下一个阶段被使用时,需要合并小文件;多个小文件如果被reduce处理的话,就需要有很多个reduce数;

2)  初始化和创建Map的开销很大;

3)  如果一个任务有很多小文件(远远小于块大小128m),则每个小文件也会被当做一个块,用一个map任务来完成,而一个map任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。而且,同时一个JOB可执行的map数也是受限的

Map数太小将导致:

1)  文件处理或查询并发度小,Job执行时间过长;

2)  大量作业时,容易堵塞集群;

3)  频繁推测执行;

是不是保证每个map处理接近128M的文件块,就高枕无忧了?

答案也是不一定。比如有一个127m的文件,正常会用一个map去完成,但这个文件只有一个或者两个小字段,却有几千万的记录,如果map处理的逻辑比较复杂,用一个map任务去做,肯定也比较耗时。

3、设定map数:mapred.map.tasks

当input的文件都很大,任务逻辑复杂,map执行非常慢的时候,可以考虑增加Map数,来使得每个map处理的数据量减少,从而提高任务的执行效率;

hive中map数默认值是2;

案例环境描述:

hive.merge.mapredfiles=true (默认是false,可以在hive-site.xml里配置,在整个job执行后合并)

hive.merge.mapfiles=true  map执行后合并

hive.merge.size.per.task=256000000

mapred.map.tasks=2   hive中map数默认是2

因为合并小文件默认是true,而dfs.block.size与hive.merge.size.per.task的搭配使得合并后的绝大部分文件都在256M左右;

案例一:

现在我们假设有3个300MB大小的文件,每个BLOCK大小为256M而且不设定map数;

整个JOB会有6个map,其中3个map分别处理256MB的数据,还有3个map分别处理44MB的数据;

木桶效应就来了,整个JOB的map阶段的执行时间不是看最短的1个map的执行时间,而是看最长的1个map的执行时间。所以,虽然有3个map分别只处理44MB的数据,可以很快跑完,但它们还是要等待另外3个处理256MB的map。显然,处理256MB的3个map拖了整个JOB的后腿。

案例二:

如果我们把mapred.map.tasks设置成6,再来看一下有什么变化:

goalsize = min(900MB/6,256MB) = 150MB

整个JOB同样会分配6个map来处理,每个map处理150MB的数据,非常均匀,谁都不会拖后腿,最合理地分配了资源,执行时间大约为CASE 1的59%(150/256)

案例三:

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(几百万记录)的数据,效率肯定会好很多。

4、Map数总结

看上去,貌似这两种有些矛盾,一个是要合并小文件,一个是要把大文件拆成小文件,这点正是重点需要关注的地方, 根据实际情况,控制map数量需要遵循两个原则:

1)   使大数据量利用合适的map

2)   使单个map任务处理合适的数据量

Hive参数层面优化之一控制Map数,布布扣,bubuko.com

时间: 2024-12-15 01:34:03

Hive参数层面优化之一控制Map数的相关文章

Hive参数层面优化之二控制Reduce数

Reduce数决定中间或落地文件数,文件大小和Block大小无关. 1.Reduce个数的决定因素 reduce个数的设定极大影响任务执行效率,不指定reduce个数的情况下,Hive会猜测确定一个reduce个数,基于以下两个设定: 参数1:hive.exec.reducers.bytes.per.reducer(每个reduce任务处理的数据量,默认为1000^3=1G) 参数2:hive.exec.reducers.max(每个作业最大的reduce数,默认为999) 计算reducer数

Hive调优(语法与参数层面优化)

一.简介 作为企业Hadoop应用的核心产品,Hive承载着FaceBook.淘宝等大佬 95%以上的离线统计,很多企业里的离线统计甚至全由Hive完成,如我所在的电商.Hive在企业云计算平台发挥的作用和影响愈来愈大,如何优化提速已经显得至关重要. 好的架构胜过任何优化,好的Hql同样会效率大增,修改Hive参数,有时也能起到很好的效果. 有了瓶颈才需要优化 1.Hadoop的主要性能瓶颈是IO负载,降IO负载是优化的重头戏. 2.对中间结果的压缩 3.合理设置分区,静态分区和动态分区 二.H

Hive语法层面优化之一数据倾斜介绍

数据倾斜:数据分布不均匀,造成数据大量的集中到一点,造成数据热点: 由于数据并不是平均分配的,会导致各个节点上处理的数据量是不均衡的,所以数据倾斜是无法避免的: 造成数据倾斜的最根本原因:key分发不均匀造成的: 常见的数据倾斜的症状 1)  Map阶段快,reduce阶段非常慢: 2)  某些map很快,某些map很慢: 3)  某些reduce很快,某些reduce很慢: 4)  任务进度长时间维持在99%(或100%),查看任务监控页面,发现只有少量(1个或几个)reduce子任务未完成,

Hive语法层面优化之四count(distinct)引起的数据倾斜

当该字段存在大量值为null或空的记录,容易发生数据倾斜: 解决思路: count distinct时,将值为空的情况单独处理,如果是计算count distinct,可以不用处理,直接过滤,在最后结果中加1: 如果还有其他计算,需要进行group by,可以先将值为空的记录单独处理,再和其他计算结果进行union. 案例: select count(distinct end_user_id) as user_num from trackinfo; 调整为: select cast(count(

Hive语法层面优化之五分析执行计划追踪导致数据倾斜的原因

count(distinct key)案例 explain select count(distinct session_id) from trackinfo where ds=' 2013-07-21' ; STAGE DEPENDENCIES: Stage-1 is a root stage Stage-0 is a root stage STAGE PLANS: Stage: Stage-1 Map Reduce Alias -> Map Operator Tree: trackinfo T

Hive架构层面优化之二合理利用中间结果集(单Job)

是针对单个作业,针对本job再怎么优化也不会影响到其他job: Hadoop的负载主要有两部分:CPU负载和IO负载: 问题:机器io开销很大,但是机器的cpu开销较小,另外map输出文件也较大,怎么办? 解决办法:通过设置map的中间输出进行压缩就可以了,这个不会影响最终reduce的输出. 集群中的机器一旦选定了,那么CPU就没的改变了,所以集群的最主要的负载还是IO负载: 压缩技术虽然可以降低IO负载,但是同时也加重了CPU负载,治标不治本,CPU加重了,整体性能还是上不去:如果当前CPU

Hive架构层面优化之六分布式缓存

案例: Hadoop jar引用:hadoop jar -libjars aa.jar bb.jar …. jar包会被上传到hdfs,然后分发到每个datanode 假设有20个jar文件,每天jar文件被上传上万次,分发达上万次(百G级),造成很严重的IO开销. 如何使这些jar包在HDFS上进行缓存,同一个jar只需上传和分发一次,后续所有的job可以节省此jar的上传和分发的开销,从而减少不必要的上传和分发呢? 解决方案:使用分布式缓存 MapReduce如何使用分布式缓存 Hadoop

Hive架构层面优化之七压缩

常见的压缩有:对中间结果压缩.对输出结果压缩. 压缩对比: 算法 压缩前/压缩后 压缩速度 解压速度 GZIP 13.4% 21MB/s 118 MB/s LZO 20.5% 135 MB/s 410 MB/s Snappy 22.2% 172 MB/s 409 MB/s Snappy介绍: Snappy 网站:http://code.google.com/p/snappy/ Snappy的前身是Zippy.虽然只是一个数据压缩库,它却被Google用于许多内部项目程,其中就包括BigTable

Hive架构层面优化之四 常用复杂/低效的统计从源上给出,以避免上层作业过多计算

案例一:trackinfo,基础表处理常用的低性能UDF 背景描述:日志信息10分钟加载一次到实时日志表trackreal中(按小时分区),为了保证实时性,在加载的过程中并没有做任何的过滤处理,加载到trackreal表后再过滤非法数据.爬虫数据等,生成按天增量日志表trackinfo,然后根据不同的page_type来统计流量. 解决方案如下: select '首页', count(*) pv, #每条记录就是一条pv count(distinct session_id) uv #根据sess