如何控制hadoop中map和reduce任务的数量

APS生产排程系统——ERP、MES、APS系统的关联和区别 阅读详情

很多文档中描述,Mapper的数量在默认情况下不可直接控制干预,因为Mapper的数量由输入的大小和个数决定。在默认情况下,最终input占据了多少block,就应该启动多少个Mapper。如果输入的文件数量巨大,但是每个文件的size都小于HDFS的blockSize,那么会造成启动的Mapper等于文件的数量(即每个文件都占据了一个block),那么很可能造成启动的Mapper数量超出限制而导致崩溃。这些逻辑确实是正确的,但都是在默认情况下的逻辑。其实如果进行一些客户化的设置,就可以控制了。

在Hadoop中,设置Map task的数量不像设置Reduce task数量那样直接,即:不能够通过API直接精确的告诉Hadoop应该启动多少个Map task。

你也许奇怪了,在API中不是提供了接口org.apache.hadoop.mapred.JobConf.setNumMapTasks(int n)吗?这个值难道不可以设置Map task的数量吗?这个API的确没错,在文档上解释”Note: This is only a hint to the framework.“,即这个值对Hadoop的框架来说仅仅是个提示,不起决定性的作用。也就是说,即便你设置了,也不一定得到你想要的效果。


1. InputFormat介绍

在具体设置Map task数量之前,非常有必要了解一下与Map-Reduce输入相关的基础知识。

这个接口(org.apache.hadoop.mapred.InputFormat)描述了Map-Reduce job的输入规格说明(input-specification),它将所有的输入文件分割成逻辑上的InputSplit,每一个InputSplit将会分给一个单独的mapper;它还提供RecordReader的具体实现,这个Reader从逻辑的InputSplit上获取input records并传给Mapper处理。

InputFormat有多种具体实现,诸如FileInputFormat(处理基于文件的输入的基础抽象类), DBInputFormat(处理基于数据库的输入,数据来自于一个能用SQL查询的表),KeyValueTextInputFormat(特殊的FineInputFormat,处理Plain Text File,文件由回车或者回车换行符分割成行,每一行由key.value.separator.in.input.line分割成Key和Value),CompositeInputFormat,DelegatingInputFormat等。在绝大多数应用场景中都会使用FileInputFormat及其子类型。

通过以上的简单介绍,我们知道InputFormat决定着InputSplit,每个InputSplit会分配给一个单独的Mapper,因此InputFormat决定了具体的Map task数量。


2. FileInputFormat中影响Map数量的因素

在日常使用中,FileInputFormat是最常用的InputFormat,它有很多具体的实现。以下分析的影响Map数量的因素仅对FileInputFormat及其子类有效,其他非FileInputFormat可以去查看相应的 getSplits(JobConf job, int numSplits) 具体实现即可。

请看如下代码段(摘抄自org.apache.hadoop.mapred.FileInputFormat.getSplits,hadoop-0.20.205.0源代码):

  1. long goalSize = totalSize / (numSplits == 0 ? 1 : numSplits); 
  2. long minSize = Math.max(job.getLong("mapred.min.split.size", 1), minSplitSize); 
  3.  
  4. for (FileStatus file: files) { 
  5.   Path path = file.getPath(); 
  6.   FileSystem fs = path.getFileSystem(job); 
  7.   if ((length != 0) && isSplitable(fs, path)) {  
  8.     long blockSize = file.getBlockSize(); 
  9.     long splitSize = computeSplitSize(goalSize, minSize, blockSize); 
  10.      
  11.     long bytesRemaining = length; 
  12.     while (((double) bytesRemaining)/splitSize > SPLIT_SLOP) { 
  13.       String[] splitHosts = getSplitHosts(blkLocations,length-bytesRemaining, splitSize, clusterMap); 
  14.       splits.add(new FileSplit(path, length-bytesRemaining, splitSize, splitHosts)); 
  15.       bytesRemaining -= splitSize; 
  16.     } 
  17.  
  18.     if (bytesRemaining != 0) { 
  19.       splits.add(new FileSplit(path, length-bytesRemaining, bytesRemaining, blkLocations[blkLocations.length-1].getHosts())); 
  20.     } 
  21.   } else if (length != 0) { 
  22.     String[] splitHosts = getSplitHosts(blkLocations,0,length,clusterMap); 
  23.     splits.add(new FileSplit(path, 0, length, splitHosts)); 
  24.   } else {  
  25.     //Create empty hosts array for zero length files 
  26.     splits.add(new FileSplit(path, 0, length, new String[0])); 
  27.   } 
  28. } 
  29.  
  30. return splits.toArray(new FileSplit[splits.size()]); 
  31.  
  32. protected long computeSplitSize(long goalSize, long minSize, long blockSize) { 
  33.     return Math.max(minSize, Math.min(goalSize, blockSize)); 
  34. } 
long goalSize = totalSize / (numSplits == 0 ? 1 : numSplits);
long minSize = Math.max(job.getLong("mapred.min.split.size", 1), minSplitSize);

for (FileStatus file: files) {
  Path path = file.getPath();
  FileSystem fs = path.getFileSystem(job);
  if ((length != 0) && isSplitable(fs, path)) { 
    long blockSize = file.getBlockSize();
    long splitSize = computeSplitSize(goalSize, minSize, blockSize);
    
    long bytesRemaining = length;
    while (((double) bytesRemaining)/splitSize > SPLIT_SLOP) {
      String[] splitHosts = getSplitHosts(blkLocations,length-bytesRemaining, splitSize, clusterMap);
      splits.add(new FileSplit(path, length-bytesRemaining, splitSize, splitHosts));
      bytesRemaining -= splitSize;
    }

    if (bytesRemaining != 0) {
      splits.add(new FileSplit(path, length-bytesRemaining, bytesRemaining, blkLocations[blkLocations.length-1].getHosts()));
    }
  } else if (length != 0) {
    String[] splitHosts = getSplitHosts(blkLocations,0,length,clusterMap);
    splits.add(new FileSplit(path, 0, length, splitHosts));
  } else { 
    //Create empty hosts array for zero length files
    splits.add(new FileSplit(path, 0, length, new String[0]));
  }
}

return splits.toArray(new FileSplit[splits.size()]);

protected long computeSplitSize(long goalSize, long minSize, long blockSize) {
    return Math.max(minSize, Math.min(goalSize, blockSize));
}

totalSize:是整个Map-Reduce job所有输入的总大小。

numSplits:来自job.getNumMapTasks(),即在job启动时用org.apache.hadoop.mapred.JobConf.setNumMapTasks(int n)设置的值,给M-R框架的Map数量的提示。

goalSize:是输入总大小与提示Map task数量的比值,即期望每个Mapper处理多少的数据,仅仅是期望,具体处理的数据数由下面的computeSplitSize决定。

minSplitSize:默认为1,可由子类复写函数protected void setMinSplitSize(long minSplitSize) 重新设置。一般情况下,都为1,特殊情况除外。

minSize:取的1和mapred.min.split.size中较大的一个。

blockSize:HDFS的块大小,默认为64M,一般大的HDFS都设置成128M。

splitSize:就是最终每个Split的大小,那么Map的数量基本上就是totalSize/splitSize。

接下来看看computeSplitSize的逻辑:首先在goalSize(期望每个Mapper处理的数据量)和HDFS的block size中取较小的,然后与mapred.min.split.size相比取较大的。


3. 如何调整Map的数量

有了2的分析,下面调整Map的数量就很容易了。


3.1 减小Map-Reduce job 启动时创建的Mapper数量

当处理大批量的大数据时,一种常见的情况是job启动的mapper数量太多而超出了系统限制,导致Hadoop抛出异常终止执行。解决这种异常的思路是减少mapper的数量。具体如下:

3.1.1 输入文件size巨大,但不是小文件

这种情况可以通过增大每个mapper的input size,即增大minSize或者增大blockSize来减少所需的mapper的数量。增大blockSize通常不可行,因为当HDFS被hadoop namenode -format之后,blockSize就已经确定了(由格式化时dfs.block.size决定),如果要更改blockSize,需要重新格式化HDFS,这样当然会丢失已有的数据。所以通常情况下只能通过增大minSize,即增大mapred.min.split.size的值。


3.1.2 输入文件数量巨大,且都是小文件

所谓小文件,就是单个文件的size小于blockSize。这种情况通过增大mapred.min.split.size不可行,需要使用FileInputFormat衍生的CombineFileInputFormat将多个input path合并成一个InputSplit送给mapper处理,从而减少mapper的数量。具体细节稍后会更新并展开。


3.2 增加Map-Reduce job 启动时创建的Mapper数量

增加mapper的数量,可以通过减小每个mapper的输入做到,即减小blockSize或者减小mapred.min.split.size的值。


参考资料

http://yaseminavcular.blogspot.com/2011/06/how-to-set-number-of-maps-with-hadoop.html

http://svn.apache.org/repos/asf/hadoop/common/tags/release-0.20.205.0

Unity物理引擎实战:从刚体重心到碰撞体,打造真实不倒翁交互 刚体(Rigidbody)是Unity物理系统的核心组件,它定义了游戏对象的物理属性,如质量、阻力和碰撞响应。其原理基于牛顿力学,通过物理引擎(如PhysX)实时计算物体的运动状态。在游戏开发中,刚体的价值在于能够模拟真实世界的物理行为,为玩家提供沉浸式的交互体验。碰撞体(Collider)则定义了物体的形状边界,用于检测与其他物体的接触。通过精细调整刚体的重心(Center of Mass)和碰撞体形状,开发者可以模拟出各种有趣的物理现象,例如低重心物体的动态平衡。这在休闲游戏、物理玩具模拟等场景中尤为实 阅读详情

相关推荐

总结:知识图谱KG+大模型LLM

知识图谱KG+大模型LLM

安静的软件工程师 4201

深度分析如何在Hadoop中控制Map的数量

深度分析如何在Hadoop中控制Map的数量 guibin.beijing@gmail.com 很多文档中描述,Mapper的数量在默认情况下不可直接控制干预,因为Mapper的数量由输入的大小和个数决定。在默认情况下,最终input占据了多少block,就应该启动多少个Mapper。如果输入的文件数量巨大,但是每个文件的size都小于HDFS的blockSize,那么会造成启动的Mapp...

蓝色妖姬 506

【LDLTS解析】从重叠峰到精准参数:拉普拉斯深能级瞬态光谱如何重塑半导体缺陷分析

本文深入解析了拉普拉斯深能级瞬态光谱(LDLTS)技术如何革新半导体缺陷分析。针对传统DLTS难以分辨重叠峰的痛点,LDLTS通过拉普拉斯逆变换对高精度电容瞬态曲线进行数学解卷积,成功分离发射率相近的缺陷信号,实现从模糊宽峰到精准独立峰的转变。该技术不仅大幅提升了缺陷激活能和捕获截面等关键参数的提取精度,更推动分析范式从经验拟合转向第一性原理,为先进半导体工艺开发与良率提升提供了强大的精准诊断工具。

weixin_29224309的博客 272

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

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

yuan_53yuan的博客 1920

AXI_IIC读写操作

其实在之前调试过一次AXI_IIC,没调试通,碍于赶进度,就直接使用了zynq-PS侧的IIC,就一直搁置着了,这次抽空将这部分内容继续调试下去,这一次没花多少时间就调通了,现在将我的调试过程,经历,以及参考文档如下: 参考文档:pg090-axi-iic.pdf 参考链接:https://forums.xilinx.com/t5/Design-and-Debug-Techniques-Blog/IIC-Protocol-and-Programming-Sequence/ba-p/1072248 上面的这个

qq_32134427的博客 1万+

Android逆向分析

Android 逆向开发是指对已发布的 Android 应用进行分析和破解,以了解应用程序的内部工作原理,获取应用程序的敏感信息,或者修改应用程序的行为。Android应用 Java编写的,利用Android SDK编译代码,并并且把所有的数据和资源文件打包成一个APK(Android Package)文件这是一个后缀名为.apk的压缩文件,apk文件中包含了一个Anddroid应用程序的所有内容,是Android平台用于安装应用程序的文件。

qq_51598534的博客 6293

MapReduce之mapper以及reducer的个数决定性因素

这个图大概可以描述mapreduce计算模型的执行过程,下面我们就围绕这个图聊几个问题,其中有工作中非常有用的问题: 1. mapper的个数  结论:mapper的个数是由输入数据的大小决定的,一般不需要我们去设置,如果你想控制mapper的个数,那么需要先了解hadoop是怎么控制mapper的个数。  如图所示,每个Mapper Tasker对应一个split(切片),要处理的file...

LJJ1338的博客 7841

OpenClaw 在 Windows 环境下的完整安装、配置和部署指南

介绍Windows环境下OpenClaw的完整安装,配置和部署的全流程

hxbao的专栏 1485

如何在hadoop中控制map的个数

hadooop提供了一个设置map个数的参数mapred.map.tasks,我们可以通过这个参数来控制map的个数。但是通过这种方式设置map的个数,并不是每次都有效的。原因是mapred.map.tasks只是一个hadoop的参考数值,最终map的个数,还取决于其他的因素。      为了方便介绍,先来看几个名词: block_size : hdfs的文件块大小,默认为64M,可以通过参

lylcore的专栏 2万+

NVIDIA驱动装好了,Gazebo为啥还是卡?手把手教你用optirun搞定GPU加速

本文详细解析了NVIDIA驱动安装后Gazebo仍卡顿的原因,并提供三步精准诊断与GPU加速实战方案。通过optirun快速启用GPU加速,解决OpenGL与显示服务器的配置问题,显著提升仿真性能。适用于ROS、PX4等开发环境,帮助用户充分利用显卡性能。

weixin_30379531的博客 464

注意力机制模块:CA(坐标注意力)二次创新:融合深度可分离卷积,打造 CADS 模块

本文提出CADS模块,将坐标注意力(CA)与深度可分离卷积(DSC)深度融合,优化移动端AI部署效率。通过重构CA的计算范式,用深度卷积替代传统1×1卷积,在保持精度的同时显著降低计算开销。文章深入分析了CA的计算瓶颈和DSC的实际效率问题,详细阐述了CADS的设计原理与PyTorch实现,并提供了多组性能对比数据。该模块可直接应用于YOLO、UNet等主流模型,为移动端AI部署提供高效解决方案。

ZXSXJ的博客 96

Hadoop的MR程序中map的个数

map的个数是由输入所分成的split的个数决定的,有多少个split,就会有多少个map任务。

无他,唯程序尔 4872

【人脸识别】基于 Gabor+SVM和PCA+SVM实现人脸识别matlab源码含 GUI

1 简介 随着经济的快速发展,互联网的普及,信息安全逐渐被人们所重视。人脸识别技术作为保护信息安全的重要手段之一,也逐渐被研究学者所重视。人脸识别作为计算机视觉技术和生物特征识别技术的一个重要分支,模式识别与人工智能的一个重要领域,其主要任务是对静态图像或动态视频进行识别。如何快速的正确的对人脸进行识别是目前人脸识别课题的一个难题。人脸识别算法的选取直接关系到人脸识别的识别率。 本文首先介绍了国内外人脸识别的发展现状,并对人脸图像预处理方法进行了详细阐述。图像预处理的方法有很多,主要包括:灰度变换、图像锐

qq_59747472的博客 1135

Hadoop2调优(一):如何控制job的map任务和reduce任务的数量

在运行MapReduce任务的时候如何避免这种情况! 100多个map任务,但是只有1个reduce任务; 此时在mapred-site.xml中修改配置 mapred.map.tasks10As a rule of thumb, use 10x the number of slaves(i.e., number of tasktrackers).          

guoyunyuhou的专栏 1850

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Mapreduce任务中map和reduce数量设置

从MR的运行机制可知,map数量受split(map输入数据块大小)影响,reduce数量受partition(map shuffle输出)影响。 1.map数量设置 hadoop并没有直接提供设置map数量的参数,而是通过调整split块大小调整,通过调整hadoop2.x mapreduce.input.fileinputformat.split.maxsize和mapreduce.input...

forerunner123的博客 2122

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Hive性能调优之合理调整Map与Reduce数量

合理设置map数量 map阶段主要涉及两个问题:小文件太多或者大文件过于负责。 对应的解决方案就是减少map数量与增加map数量。 减少map数就是增加每个map处理的文件数量,用于处理大量小文件,间接加快速度。 -- CombineHiveInputFormat有对小文件合并的处理,hive2.X已经默认使用CombineHiveInputFormat set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

qq_41676216的博客 835

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Hive合理设置 Map 及 Reduce 数

合理设置 Map 及 Reduce 数 1)通常情况下,作业会通过 input 的目录产生一个或者多个 map 任务。 主要的决定因素有:input 的文件总个数,input 的文件大小,集群设置的文件块大小。 2)是不是 map 数越多越好? 答案是否定的。如果一个任务有很多小文件(远远小于块大小 128m),则每个小文件 也会被当做一个块,用一个 map 任务来完成,而一个 map 任务启动和初始化的时间远远大 于逻辑处理的时间,就会造成很大的资源浪费。而且,同时可执行的 map

song_quan_的博客 1641

Hive如何设置Map个数和Reduce个数

根据输入文件估算Reduce的个数可能未必很准确,因为Reduce的输入是Map的输出,而Map的输出可能会比输入要小,所以最准确的数根据Map的输出估算Reduce的个数。比如有一个127M的文件,正常会用一个map去完成,但这个文件只有一个或者两个小字段,却有几千万的记录,如果map处理的逻辑比较复杂,用一个map任务去做,肯定也比较耗时。从Hive的角度看,小文件会开很多map,一个map开一个JVM去执行,所以这些任务的初始化,启动,执行会浪费大量的资源,严重影响性能。...

weixin_47681855的博客 4240

Mapreduce和Hive中map reduce个数设定

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

qq_36588424的博客 1526

【Hadoop】Map和Reduce个数问题

在hadoop中当一个任务没有设置的时候,该任务的执行的map的个数是由任务本身的数据量决定的,具体计算方法会在下文说明;而reduce的个数hadoop是默认设置为1的。为何设置为1那,因为一个任务的输出的文件个数是由reduce的个数来决定的。一般一个任务的结果默认是输出到一个文件中,所以reduce的数目设置为1。那如果我们为了提高任务的执行速度如何对map与reduc...

weixin_33935505的博客 136

关于map task和reduce task的个数

先引用几段话: 1.[url]http://coderplay.iteye.com/blog/318602[/url] 11 楼 riddle_chen 2009-05-05 引用 jiwenke 写道 coderplay 写道sorry,理解能力太差, 我不是很明白你的意思.如果你是需要控制单个节点同时在执行的的mapper/reducer数.你可以通过修改slave节点配...

gushuizerotoone的博客 554

Hadoop提交MR任务的命令

mapreduce.map.java.opts=-Xmx1638m 这个是设置Map任务暂用JVM堆内存大小为1638MB(留一些内存给JVM进程本身)。mapreduce.reduce.java.opts=-Xmx3276m 设置Reduce任务的JVM堆内存大小为3276MB。mapreduce.reduce.memory.mb=4096 设置每个Reduce任务的内存为4096MB。mapreduce.map.memory.mb=2048 设置每个Map任务的内存为2048MB。

别人笑我太疯癫,我笑他人看不穿。 904

运行中hadoop任务修改/kill

操作 命令 kill任务 hadoop job -kill ${job-id} 修改优先级 hadoop job -set-priority ${job-id} ${priority} 修改map并发 hadoop job -set-map-capacity ${job-id} $n 修改reduce并

mirror的专栏 1524

Map Reducer的初认识

主要的各个阶段 在Split 分片阶段, — 只需要知道有这个阶段就有了,具体大小的关系,如何计算的 所有的输入都会被分成若干个分片,即对对输入的所有文件在block中形成Z个分片。 一个分片(split)会要对应下游一个Map Task。 输入文件默认是要保存到 NataNode的block块中,Hadoop2.x默认的block大小为128MB(可以在hdfs-site.xml中设置参数dfs.block.size) 在分片阶段,所有的输入文件都会被计算分配到相应的block中, ...

wangwangstone的博客 383

Hadoop实战问题集锦

(1)如何获取当前split的文件名: 答案:InputSplit split=context.getInputSplit(); String filename=((FileSplit)split).getPath().toString();

linux系统、网络编程和分布式计算 1356
上一篇: iterable和iterator接口的区别
下一篇: oracle中关于rownum的用法
爪爪的瓜瓜
博客等级 码龄14年 5粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值