Hive合并小文件,减小map数

Hive合并小文件,减小map数

配置文件中设置的参数的含义

1.限制Map,Reduce数

map/reduce限制Map,Reduce数
mapset mapreduce.tasktracker.map.tasks.maximum=30; --每个nodemanager节点上可运行的最大map任务数,默认值2,可根据实际值调整为10~100;
reduceset mapreduce.tasktracker.reduce.tasks.maximum=30; --每个nodemanager节点上可运行的最大reduce任务数,默认值2,可根据实际值调整为10~100;

2.MR输出时合并小文件

参数设置含义
set hive.merge.mapfiles=true;在Map-only的任务结束时合并小文件
set hive.merge.mapredfiles=true;在Map-Reduce的任务结束时合并小文件
set hive.merge.size.per.task=128000000;$1
set hive.merge.smallfiles.avgsize=128000000;当输出文件的平均大小小于128M时,启动一个独立的map-reduce任务进行文件merge

3.将多个小文件打包作为一个整体的inputsplit,减少map任务数 大小关系:maxSplitSize > minSplitSizeNode > minSplitSizeRack

set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

参数设置含义
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
set mapreduce.input.fileinputformat.split.maxsize=128000000;切片大小最大值,不设置,则所有输入只启动一个map任务
set mapreduce.input.fileinputformat.split.minsize.per.node=16000000;同一节点的数据块形成切片时,切片大小的最小值
set mapreduce.input.fileinputformat.split.minsize.per.rack=16000000;同一机架的数据块形成切片时,切片大小的最小值
set mapred.max.split.size=128000000;最大split大小
set mapred.min.split.size.per.node=16000000;一个节点上最小的split大小
set mapred.min.split.size.per.rack=16000000;一个机架上最小的split大小
set spark.yarn.queue=root.super;
set mapred.job.queue.name=root.super;
set hive.auto.convert.join=true;(大表关联小表,把小表自动加载到内存中,相当于写了一个mapjoin)
set hive.exec.parallel=true;(在同一个sql中的不同的job是否可以同时运行)
set hive.exec.parallel.thread.number=20;-
set mapreduce.job.reduce.slowstart.completedmaps=0.5;(当Map Task完成的比例达到该值后才会为Reduce Task申请资源,默认是0.05)
set hive.exec.reducers.bytes.per.reducer=512000000;(每个reduce任务处理的数据量,默认为1G)
set hive.mapred.mode=nonstrict;-
set mapred.map.tasks=132;
set mapred.reduce.tasks=337;

解读:CombineFileInputFormat类

MR-Job默认的输入格式FileInputFormat为每一个小文件生成一个切片。CombineFileInputFormat通过将多个“小文件”合并为一个"切片"(在形成切片的过程中也考虑同一节点、同一机架的数据本地性),让每一个Mapper任务可以处理更多的数据,从而提高MR任务的执行速度。详见 MR案例: CombineFileInputFormat类

1).三个重要的属性:

maxSplitSize:切片大小最大值。可通过属性 “mapreduce.input.fileinputformat.split.maxsize” 或 CombineFileInputFormat.setMaxInputSplitSize()方法进行设置【不设置,则所有输入只启动一个map任务】
minSplitSizeNode:同一节点的数据块形成切片时,切片大小的最小值。可通过属性 “mapreduce.input.fileinputformat.split.minsize.per.node” 或 CombineFileInputFormat.setMinSplitSizeNode()方法进行设置
minSplitSizeRack:同一机架的数据块形成切片时,切片大小的最小值。可通过属性 “mapreduce.input.fileinputformat.split.minsize.per.rack” 或 CombineFileInputFormat.setMinSplitSizeRack()方法进行设置
大小关系:maxSplitSize > minSplitSizeNode > minSplitSizeRack
2).切片的形成过程:

2.1. 不断迭代节点列表,逐个节点 (以数据块为单位) 形成切片(Local Split)

a. 如果maxSplitSize == 0,则整个节点上的Block数据形成一个切片

b. 如果maxSplitSize != 0,遍历并累加每个节点上的数据块,如果累加数据块大小 >= maxSplitSize,则将这些数据块形成一个切片。继续该过程,直到剩余数据块累加大小 < maxSplitSize 。则进行下一步

c. 如果剩余数据块累加大小 >= minSplitSizeNode,则将这些剩余数据块形成一个切片。继续该过程,直到剩余数据块累加大小 < minSplitSizeNode。然后进行下一步,并这些数据块留待后续处理

2.2. 不断迭代机架列表,逐个机架 (以数据块为单位) 形成切片(Rack Split)
  a. 遍历并累加这个机架上所有节点的数据块 (这些数据块即上一步遗留下来的数据块),如果累加数据块大小 >= maxSplitSize,则将这些数据块形成一个切片。继续该过程,直到剩余数据块累加大小<maxSplitSize。则进行下一步

b. 如果剩余数据块累加大小 >= minSplitSizeRack,则将这些剩余数据块形成一个切片。如果剩余数据块累加大小 < minSplitSizeRack,则这些数据块留待后续处理

2.3. 遍历并累加所有Rack上的剩余数据块,如果累加数据块大小 >= maxSplitSize,则将这些数据块形成一个切片。继续该过程,直到剩余数据块累加大小< maxSplitSize。则进行下一步

2.4. 将最终剩余的数据块形成一个切片。
Demo:
规定:maxSplit=100 > minSizeNode=50 > minSizeRack=30
原有文件:Rack01:{[30,60,70] [80,110]}   Rack02:{170}  
处理过程:
30+60+70 > 100 ? 100+60  80+110 > 100 ? 100+90  170 > 100 ? 100+70  
  —>  3个数据切片,以及Rack01:{[60] [90]}  Rack02:{70}  
    —>  60 > 50 ? 50+10  90 > 50 ? 50+40  70 > 50 ? 50+20  
      —>  3+3个数据切片,以及Rack01:{[10] [40]}  Rack02:{20}  
        —>  10+40 < 100 ?0  20 < 100 ? 0  
          —>  3+3+0个数据切片,以及Rack01:{50}  Rack02:{20}  
            —>  50+20 > 30 ? 30+30+10  
              —>  3+3+0+3个数据切片

对hive输入格式设置为CombineHiveInputFormat的进行分析map数是如何计算的

set hive.input.format=org.apache.hadoop.hive.al.io.CombineHiveInputFormat

注:对orcformat、外表和链接文件无法使用,会转到调用父类HiveInputFormat的getsplits()函数

map数与逻辑split数是一致的,决定map的主要因素有:

1、相关表或分区input的文件个数

2、input文件的大小

3、input文件在node和rack的分布

4、set mapred.max.split.size; 最大split大小

5、set mapred.min.split.size.per.node; 一个节点上最小的split大小

6、set mapred.min.split.size.per.rack; 一个机架上最小的split大小

例如:查询相关目录下有12个input file,每个input file的大小都在100M左右,block分布如下图:

情况一:参数设置如下:set mapred.max.split.size=256000000;

set mapred.min.split.size.per.node=64000000;

set mapred.min.split.size.per.rack=64000000;

第一步:遍历node,嵌套遍历block,当block的累加值大于max.split.size时,创建一个split,小于时,但如果大于min.size.per.node,创建一个新的split,小于时暂存block,继续下一个node。这个遍历过程每个node最多生成一个split,为提高并发度,让split尽量分布到不同的node上。

node I 有三个block(A、B、E)累加值300M > 256M, 会新建一个split。

node II 只有一个C block < 256M,会进行暂存

第二步:遍历rack,嵌套遍历block,对暂存的block进行分割,当block的累加值大于max.split.size时,创建一个新的split,小于时,但如果大于min.size.per.rack,创建一个新的split,小于时暂存block,继续下一个rack

rack I 三个block(C、D、G)累加值300M > 256M,会新建一个split,继续到下一个rack

第三步:对垮rack最后溢出的block处理,当block累加值大于max.split.size时创建新的split,循环处理,最后剩的数据创建一个split

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值