hive优化2-hive的Input阶段:inputsplit与map数量、小文件
1.场景
生成太多Map时,计算任务会耗费很多时间在Map的启动上,这时候需要对Map数进行控制。
2.原理
单独配置参数:set mapred.map.tasks=tasknum时,可能无法真正的起到调节效果,原因如下:
1)默认情况Map个数defaultNum=目标数据文件总大小totalSize/hdfs文件块大小blockSize(默认128M)
2)在Hive中配置set mapred.map.tasks=tasknum时,获取的待选Map数为: taskNum1=max(mapred.map.tasks, defaultNum)
3)通过设置split数据分片切块大小 set mapred.min.split.size 时,获取的切片大小为splitSize=max(mapred.min.split.size, blockSize),则此时待选Map数tasknum2=totalSize/splitSize
4)最后,根据map数参数和split大小参数设置,实际Map个数=min(taskNum1, taskNum2)
小结:
减少Map数,要减少mapred.map.tasks的值,增大mapred.min.split.size的值;
增多Map数,要增大mapred.map.tasks的值,减少mapred.min.split.size的值
3.TIPS
hive表在HDFS以文件存储,表名、分区都是HDFS目录,每个分区下可以有多个文件(如果是日常跑批的表,一个reduce就对应一个文件)
split切片不跨文件,在小文件很多时且存储远小于1个blockSize时,每个小文件仍然会占用一个Map。
可在Hive中先设置小文件合并参数,缺点是没有小文件问题时导致额外消耗。
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat.
同样执行过程中的小文件也可以合并:
set hive.merge.mapfiles=true; 默认开启,合并只有map任务的输出文件
set hive.merge.mapredfiles; 默认开启,合并最后输出文件
set hive.merge.smallfiles.avgsize; 默认16M,当输出文件小于该值时启用一个MapReduce任务合并小文件
set hive.merge.size.per.task; 默认256M,每个任务合并后文件大小,一般设置为HDFS的blockSize。