MapReduce中的mapper个数决定(很全)

对于大数据搬砖工来说,使用MapReduce调优是家常便饭,其中就必须知晓mapper和reducer个数的决定原理,参考了很多有关mapper个数的文章,大部分都非常零散,只讲其中一两点,下面是自己拼凑总结,并结合实际经验梳理的,供参考~


 

目录

1  因素一:文件压缩算法是否支持文件分片

2  因素二:选择的InputFormat类

2.1 HiveInputFormat类

方案一:确定map个数:参考:书《Hive性能调优实战》

方案二:确定splitsize来确定map数 

2.2 CombineHiveInputFormat类

1)由以下四个参数影响

2)具体CombineHiveInputFormat类切片算法逻辑

3)具体的参数优先级(从小到大)

3  需要调整mapper个数的场景:

3.1 每一个mapper处理的数据量不均匀

1)长尾任务:某几个mapper的latency超过平均mapper的latency的2倍

2)大量小文件

情况一:来自数据源输入的小文件

情况二:MR输出的小文件,如reduce过程中产生的小文件,通过日志可以看到

3.2 数据量较大,分配到每个mapper任务处理的数据量也很大,单个mapper任务执行时间长


注:

1)对mappersplit切片:逻辑切片;对block的切片:物理切片

2)为什么默认map的split大小是hdfs中的块大小128MB呢?

        在集群中,数据被分割成多个block存在hdfs中不同的datanode上,而当一个MR任务对数据处理时,先要从datanode上获取所需数据块,而当这个MR任务的split大小刚好等于文件块大小时,直接访问本地的datanode节点,来扫描hdfs文件块,减少跨节点的文件扫描,减少网络IO

即当逻辑切片大小 = 物理切片大小,一般情况下最优

3)并行度 = 个数

4)实际 mapper个数调优需多次验证决定

  • mapper个数太多:太多的资源读取、磁盘io、网络Io、每个task创建和退出费时
  • mapper个数太少:不能充分利用资源,每个mapper处理的数据量过大,费时

 

例子:两张表join

  • 大表总共158749566行,文件总大小4.4G,存储个数22个文件,每个大小200Mb左右。
  • 小表总共1979375 行,文件大小50.7Mb,存储个数2个文件,大小50Mb以内。

1  因素一:文件压缩算法是否支持文件分片

  • 在map阶段,会先进入InputFormat判断:
  • InputFormat类,用于对MapReduce作业输入的处理,InputFormat涉及3个接口/类,即InputFormat、InputSplit和RecordReader。
  • 分别用来获取文件的逻辑切片,按照切片指定输入到一个个map;获取分片大小、将数据转化为kv值
  • 其中下列的文件压缩算法不支持文件切片,此时一个map任务处理的数据量会>=每个文件的大小

例子:当压缩方式为deflate时:

使用不同参数执行上面代码产生的map---------------------------------
--1.
使用系统配置的默认值
set mapred.max.split.size  = 256000000; --
set mapred.min.split.size = 256000000;
Hadoop job information for Stage-1: number of mappers: 24; number of reducers: 17

--2.降低系统默认值
set mapred.max.split.size=134217728;
set mapred.min.split.size=134217728;
Hadoop job information for Stage-1: number of mappers: 24; number of reducers: 17

--3.调高系统默认值
set mapred.max.split.size=500000000;
set mapred.min.split.size=256000000;
Hadoop job information for Stage-1: number of mappers: 9; number of reducers: 17

--4.调高系统默认值
set mapred.max.split.size=1024000000;
set mapred.min.split.size=1024000000;
Hadoop job information for Stage-1: number of mappers:6 ; number of reducers: 17

  • 发现:当降低splitsize参数值,本应增加map的个数,但是实际的map数量没变,而调高splitsize参数值时,本应减少map个数,实际上也减少了。
  • 因为此时不支持对文件切分(即逻辑切分),map处理的数据量必须大于等于文件的大小,所以调低参数<文件大小时,也没用,而如果增大splitsize,相当于增大了一个map处理的数据量。
  • 因为deflate压缩算法虽然不支持文件切分,但是可以进行文件合并。而从hive0.5开始就默认map前进行小文件合并了(默认的InputFormat类是CombineHiveInputFormat)

2  因素二:选择的InputFormat类

  • HiveInputFormat类和CombineHiveInputFormat类都是继承自InputFormat类,但是从hive0.5开始默认是CombineHiveInputFormat类
  • 不同的类,决定mapper个数的参数不一样,但都要从两方面来考虑:参数、参数优先级

2.1 HiveInputFormat类

注:

  • 使用 HiveInputFormat类的企业已经很少
  • 优先用方案一,方案二是方案一的简化。
方案一:确定map个数:参考:书《Hive性能调优实战》

首先取:max{defaultNum,mapred.map.tasks} 作为后续比较的备选

  • 理解:
    • 对文件的分块:物理切片;对input的数据切片:逻辑切片;defaultNum是当物理切片大小 = 逻辑切片大小时的map数量,此时两者完全匹配,减少了网络io和磁盘io,一般情况下,性能最优
    • 只有当用户指定的期望的Map大小大于defaultNum时,才会发挥出所设置的map个数参数的效果,若是小于defaultNum,则每个mapper处理的数据量都不饱和,资源浪费,都不能达到一般情况下的性能最优,所设置的参数不起作用
    • defaultNum:默认情况下Map的个数defaultNum=目标文件或数据的总大小totalSize/hdfs集群文件块的大小blockSize

其次分片大小取:max{mapred.min.split.size, blockSize} ,则个数取min{totalsize/mapred.min.split.size,totalsize/blockSize}

  • 理解当设置的mapred.min.split.size参数小于blockSize时,参数不起作用,因为一般的切片大小就为blockSize,当大于blockSize时这个参数才会有效

最后取min{max{defaultNum,mapred.map.tasks} , min{totalsize/mapred.min.split.size,totalsize/blockSize}}

即上面两个的较小值,即满足各种参数设置下的最小map数

方案二:确定splitsize来确定map数 

 参考:CSDN上的大多文章 :

真正让你明白Hive参数调优系列1:控制map个数与性能调优参数 (taodudu.cc)

hive如何调整map数和reduce数 - 简书 (jianshu.com)

(36条消息) Hive 如何确定 map 数的?_hive如何判断map个数_xinxindsj的博客-CSDN博客

(35条消息) hive执行时map任务数的确定_hive执行的job数是怎么确定的_大数据男的博客-CSDN博客

按照上面的理解:

首先取:min{goalSize,blockSize} 

  • goalSize:totalSize/mapred.map.tasks
  • 其实就相当于方案一的:max{defaultNum,mapred.map.tasks}

最后取:splitSize = max{mapred.min.split.size,min{goalSize,blockSize}}

  • 相比于方案一,少了mapred.min.split.size和blocksize的比较,因为这个时候一般map的splitsize小于等于blocksize(128Mb)

总结:按照HiveInputFormat类,mapper数量=min{max{defaultNummapred.map.tasks} , min{totalsize/mapred.min.split.size,totalsize/blockSize}} 决定mapper数量的外来参数只有mapred.map.tasks与mapred.min.split.size,当需要增加mapper数时,变大mapred.map.tasks或者变小mapred.min.split.size

2.2 CombineHiveInputFormat类

区别:CombineHiveInputFormat类相较 HiveInputFormat类自动实现对hdfs小文件的合并

map个数的计算:

1)由以下四个参数影响
  • mapred.min.split.size 或者 mapreduce.input.fileinputformat.split.minsize(Hadoop2.0版本后这个参数的名字)
  • mapred.max.split.size或者mapreduce.input.fileinputformat.split.maxsize
  • mapred.min.split.size.per.rack
  • mapred.min.split.size.per.node

还要与配置文件中的集群中可用mapper数量比较

2)具体CombineHiveInputFormat类切片算法逻辑

以下参考:(35条消息) hive执行时map任务数的确定_hive执行的job数是怎么确定的_大数据男的博客-CSDN博客

假设集群有3个机架,一共6个节点,9个block,假设每个block的大小都是100M。

设置合并后的最大分片为244M

set mapreduce.input.fileinputformat.split.maxsize=256000000;

设置一个节点上最小的分片大小,这个值设的不一样会影响分片数量。

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

设置 一个机架上最小的split大小,这个值设的不一样会影响分片数量。

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

算法过程:

简单记:先从小范围(node)的小文件(文件大小<mapred.min.split.size.per.node)开始合并,如果还有剩余的,就在这几个节点(rack)的大范围再次合并小文件,如果还有剩余,在几个rack间再次合并。

  • 节点内部

先从节点内部开始循环,机架1上node1三个分片之和为300M > 244M(设置的mapred.min.split.size.per.node一个节点最小的切片大小为244m),即A、B、C会合并为一个分片;

node2上只有一个block,大小是100M,小于节点最小分片大小,会暂时保留;node3和node2一样;

node4上有两个block,不够组成一个大分片;

  • 同一个机架的节点间

从node2的block和node4的两个block,即G/H/F会拼成一个大分片;

机架1上node3上的block F会暂时保留;

  • 机架间的合并

机架1上的F和机架2的I以及机架3上的H会组成一个大的分片;

3)具体的参数优先级(从小到大)

max.split.size <= min.split.size <= min.size.per.rack <= min.size.per.node

当四个参数设置矛盾时,系统会自动以优先级最高的参数为准,进行计算,如上面的算法说明中,mapreduce.input.fileinputformat.split.maxsize=256000000设置和 min.size.per.node一样,但是在实际中还是会将300M的合为一个分片。

注:

  • 四个参数的配置大小一般满足:

max.split.size >= min.split.size >= min.size.per.rack >= min.size.per.node

  • 在上面这个例子中mapper的个数与参数mapred.map.tasks基本无关,取上面四个参数得出的mapper数与集群中可用mapper数的较小值。

3  需要调整mapper个数的场景:

3.1 每一个mapper处理的数据量不均匀
1)长尾任务:某几个mapper的latency超过平均mapper的latency的2倍
  • 解决:
    • mapred.min.split.size
    • mapred.max.split.size
2)大量小文件

(使用默认参数的,及默认输入格式FileInputFormat的MR会为每一个小文件都生成一个切片,浪费计算资源)

  • 情况一:来自数据源输入的小文件
    • 解决:使用CombineHiveInputFormat类,来合并一个DataNode上的小文件
      • mapred.max.split.size限制合并文件数
      • mapred.min.split.size.per.node决定这个node上的文件是否需要合并
      • mapred.min.split.size.per.rack决定这个rack上的文件是否需要合并
  • 情况二:MR输出的小文件,如reduce过程中产生的小文件,通过日志可以看到
    • 解决:
      • set hive.merge.mapfiles=true;    默认值ture,在Map-only的任务结束时合并小文件
      • set hive.merge.mapredfiles=true;    默认值false,在Map-Reduce的任务结束时合并小文件
      • set hive.merge.size.per.task=256000000;    默认值256M((把处理小文件的几个mapper合成一个mapper)
      • set hive.merge.smallfiles.avgsize=16000000

(默认值16M,当输出文件的平均大小小于16M时,启动一个独立的map-reduce任务进行文件merge)

3.2 数据量较大,分配到每个mapper任务处理的数据量也很大,单个mapper任务执行时间长
  • 解决:
    • 调整mapper数,是增加还是减少验证来看哪个快,有时太多的mapper,会增加启动和退出及落盘的时间
    • splitSize = max{mapred.min.split.size,min{goalSize,blockSize}}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: MapReduce是一种分布式计算模型,其mapper和reduce是两个重要的组件。 mapper负责将输入数据分割成小块,并将每个小块映射为一组键值对。这些键值对将被传递给reduce组件进行处理。 reduce组件负责将mapper产生的键值对进行合并和归约,最终生成输出结果。 在MapReducemapper和reduce是并行执行的,可以在多个计算节点上同时运行,以提高计算效率。 ### 回答2: MapReduce是谷歌公司开发的一个分布式计算框架,它可以支持大规模的数据处理。MapReduce的核心思想是将数据分成若干个小块,然后在分布式计算集群上分别对这些数据块进行处理,最后将处理结果汇总。MapReducemapper和reduce是两个核心的组件,下面我们来详细介绍这两个组件。 Mapper MapperMapReduce一个非常重要的组件,它主要负责对输入的数据进行拆分,转换和过滤。Mapper的输入格式可以是任意的,常见的输入格式有文本、XML、CSV等。对于每一个输入数据,Mapper会按照一定的规则将其转换为一组<key, value>对,其key是转换后数据的关键字,value是转换后数据的实际值。Mapper的输出会被送到一组reduce节点上进行处理。 Reduce Reduce是MapReduce另一个重要的组件,它主要负责对 Mapper 的输出进行合并和计算。Reduce的输入格式是Mapper输出的一组<key, value>对,同样也是一个集合。Reduce会对这个集合的所有<key, value>对进行聚合操作,最终输出一个或多个最终结果。 在MapReduce的运行过程,数据首先会被拆分成不同的块,然后这些块会被分配到集群多个节点上进行批量处理。Mapper组件会对每一个块进行处理,Mapper可以在处理期间改变key和value,然后将处理结果输出到Reduce组件。Reduce会在所有Mapper组件输出结果的基础上,聚合结果集并执行最后的计算。最后,MapReduce会将计算结果输出到文件系统或其他存储介质。 总的来说,MapReducemapper和reduce组件可以将数据的繁琐处理任务分解到多个节点上同时执行,极大地提高了数据处理的效率和速度。这种方法可以在大规模数据处理和分析任务发挥非常重要的作用。 ### 回答3: MapReduce是一个并行处理数据的框架。它是由Google公司开发并在2004年的一篇论文首次提出,用于解决大规模数据处理的问题。MapReduce的工作流程主要包括两个阶段:Map阶段和Reduce阶段。 在MapReduceMapper和Reducer是两个核心组件,它们在不同的阶段扮演着重要的角色。Mapper的主要工作是将输入数据切分成若干个片段,并对每个数据片段执行一组操作,然后将结果输出到Reduce,这样Reduce就可以对Mapper输出的结果进行聚合操作。而Reducer的主要工作则是对Mapper输出的结果进行合并操作,最终输出一个或多个结果。 通常情况下,Mapper的输入是以键值对的形式提供的,而Mapper的输出也是以键值对的形式呈现的。这意味着,在Mapper可以执行各种数据操作,如过滤、排序、合并、相加等。Mapper的一个重要特征是它经常能够并行化地执行。同样,Reducer也能处理输入键值对并并行化地执行,但输出通常是一个数据值的列表而不是一个键值对。 在MapReduce,Reducer的数量可以是任意的,但通常都是由用户定义的。如果Reducer的数量比较少,则可能会导致性能问题。相反,如果Reducer的数量过多,则可能会影响MapReduce的总体性能。 总的来说,Mapper和Reducer是MapReduce最重要的组件之一。它们通过执行不同的操作,帮助大数据处理系统适应不同的需求和复杂性水平。可以说,Mapper和Reducer为大规模数据处理开辟了新的方向,这对于使用MapReduce大规模处理数据的企业和组织来说是一个重要的趋势。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值