Hadoop-2.4.1学习之怎样确定Mapper数量
MapReduce框架的优势是能够在集群中并行运行mapper和reducer任务,那怎样确定mapper和reducer的数量呢,或者说怎样以编程的方式控制作业启动的mapper和reducer数量呢?在《Hadoop-2.4.1学习之Mapper和Reducer》中以前提及建议reducer的数量为(0.95~1.75 ) * 节点数量 * 每一个节点上最大的容器数,并可用法Job.setNumReduceTasks(int)。mapper的数量由输入文件的大小确定。且没有相应的setNumMapTasks方法,但能够通过Configuration.set(JobContext.NUM_MAPS, int)设置,当中JobContext.NUM_MAPS的值为mapreduce.job.maps,而在Hadoop的官方站点上对该參数的描写叙述为与MapReduce框架和作业配置巧妙地交互。而且设置起来更加复杂。
从这样一句含糊不清的话无法得知到底怎样确定mapper的数量。显然仅仅能求助于源码了。
在Hadoop中MapReduce作业通过JobSubmitter类的submitJobInternal(Jobjob, Cluster cluster)方法向系统提交作业(该方法不仅设置mapper数量。还运行了一些其他操作如检查输出格式等,感兴趣的能够參考源码),在该方法中与设置mapper有关的代码例如以下:
int maps = writeSplits(job, submitJobDir);
conf.setInt(MRJobConfig.NUM_MAPS, maps);
LOG.info("number of splits:" + maps);
方法writeSplits返回mapper的数量,该方法的源码例如以下:
private int writeSplits(org.apache.hadoop.mapreduce.JobContext job,Path jobSubmitDir)
throws IOException,InterruptedException, ClassNotFoundException {
JobConf jConf = (JobConf)job.getConfiguration();
int maps;
if (jConf.getUseNewMapper()) {
maps = writeNewSplits(job, jobSubmitDir);
} else {
maps = writeOldSplits(jConf, jobSubmitDir);
}
return maps;
}
在该方法中,依据是否使用了新版本号的JobContext而使用不同的方法计算mapper数量。实际情况是jConf.getUseNewMapper()将返回true,因此将运行writeNewSplits(job,jobSubmitDir)语句,该方法的源码例如以下:
Configuration conf = job.getConfiguration();
InputFormat<?, ? > input = ReflectionUtils.newInstance(job.getInputFormatClass(), conf);
List<InputSplit> splits = input.getSplits(job);
T[] array = (T[]) splits.toArray(new InputSplit[splits.size()]); // sort the splits into order based on size, so that the biggest
// go first
Arrays.sort(array, new SplitComparator());
JobSplitWriter.createSplitFiles(jobSubmitDir, conf, jobSubmitDir.getFileSystem(conf), array);
return array.length;
通过上面的代码能够得知,实际的mapper数量为输入分片的数量,而分片的数量又由使用的输入格式决定,默觉得TextInputFormat,该类为FileInputFormat的子类。确定分片数量的任务交由FileInputFormat的getSplits(job)完毕,在此补充一下FileInputFormat继承自抽象类InputFormat,该类定义了MapReduce作业的输入规范,当中的抽象方法List<InputSplit> getSplits(JobContext context)定义了怎样将输入切割为InputSplit。不同的输入有不同的分隔逻辑,而分隔得到的每一个InputSplit交由不同的mapper处理,因此该方法的返回值确定了mapper的数量。以下将分为两部分学习该方法是怎样在FileInputFormat中实现的,为了将注意力集中在最重要的部分。对日志输出等信息将不做介绍,完整的实现能够參考源码。
首先是第一部分,该部分代码计算了最大InputSplit和最小InputSplit的值,例如以下:
long minSize = Math.max(getFormatMinSplitSize(), getMinSplitSize(job));
long maxSize = getMaxSplitSize(job);
当中的getMinSplitSize和getMaxSplitSize方法分别用于获取最小InputSplit和最大InputSplit的值。相应的配置參数分别为mapreduce.input.fileinputformat.split.minsize。默认值为1L和mapreduce.input.fileinputformat.split.maxsize,默认值为Long.MAX_VALUE,十六进制数值为 0x7fffffffffffffffL,相应的十进制为9223372036854775807,getFormatMinSplitSize方法返回该输入格式下InputSplit的下限。
以上数字的单位都是byte。由此得出minSize的大小为1L。maxSize的大小为Long.MAX_VALUE。
其次是生成InputSplit的第二部分。在该部分将生成包括InputSplit的List,而List的大小为InputSplit的数量,进而确定了mapper的数量。当中重要的代码为:
if (isSplitable(job, path)) {
long blockSize = file.getBlockSize();
long splitSize = computeSplitSize(blockSize, minSize, maxSize);
long bytesRemaining = length;
while (((double) bytesRemaining)/splitSize > SPLIT_SLOP) {
int blkIndex = getBlockIndex(blkLocations, length-bytesRemaining);
splits.add(makeSplit(path, length-bytesRemaining, splitSize,
blkLocations[blkIndex].getHosts()));
bytesRemaining -= splitSize;
}
if (bytesRemaining != 0) {
int blkIndex = getBlockIndex(blkLocations, length-bytesRemaining);
splits.add(makeSplit(path, length-bytesRemaining, bytesRemaining,
blkLocations[blkIndex].getHosts()));
}
}
blockSize的值为參数dfs.blocksize的值,默觉得128M。方法computeSplitSize(blockSize, minSize, maxSize)依据blockSize,minSize。maxSize确定InputSplit的大小,源码例如以下:
Math.max(minSize, Math.min(maxSize, blockSize))
从该代码并结合第一部分的分析能够得知,InputSplit的大小取决于dfs.blocksiz、mapreduce.input.fileinputformat.split.minsize、mapreduce.input.fileinputformat.split.maxsize和所使用的输入格式。
在输入格式为TextInputFormat的情况下,且不改动InputSplit的最大值和最小值的情况,InputSplit的终于值为dfs.blocksize的值。
变量SPLIT_SLOP的值为1.1。决定了当剩余文件大小多大时停止依照变量splitSize切割文件。
依据代码可知,当剩余文件小于等于1.1倍splitSize时,将把剩余的文件做为一个InputSplit。即最后一个InputSplit的大小最大为1.1倍splitSize。
总结
本文分析了在输入格式为默认的TextInputFormat的情况,怎样确定mapper的数量。在不改动源码的情况下(改动输入格式的InputSplit下限)。程序猿能够通过设置dfs.blocksiz、mapreduce.input.fileinputformat.split.minsize、mapreduce.input.fileinputformat.split.maxsize參数的值设置InputSplit的大小来影响InputSplit的数量。进而决定mapper的数量。
当输入为其他格式时,处理逻辑又不同样了,比方当输入格式为DBInputFormat时。会依据输入表的行数(记录数)决定mapper的数量。很多其他细节能够參考源码。
Hadoop-2.4.1学习之怎样确定Mapper数量的更多相关文章
- 如何确定 Hadoop map和reduce的个数--map和reduce数量之间的关系是什么?
1.map和reduce的数量过多会导致什么情况?2.Reduce可以通过什么设置来增加任务个数?3.一个task的map数量由谁来决定?4.一个task的reduce数量由谁来决定? 一般情况下,在 ...
- [Hadoop] mapper数量的控制
确定map任务数时依次优先参考如下几个原则: 1) 每个map任务使用的内存不超过800M,尽量在500M以下 比如处理256MB数据需要的时间为10分钟,内存为800MB,此时如果处理12 ...
- 开启Hadoop和Spark的学习之路
Hadoop Hadoop是一个由Apache基金会所开发的分布式系统基础架构. 用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群的威力进行高速运算和存储. Hadoop实现了一个 ...
- Hadoop 2.2.0学习笔记20131210
伪分布式单节点安装执行pi失败: [root@server- ~]# ./bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples ...
- Hadoop 2.2.0学习笔记20131209
1.下载java 7并安装 [root@server- ~]# rpm -ivh jdk-7u40-linux-x64.rpm Preparing... ####################### ...
- hadoop自带TestDFSIO学习
hadoop系统中,包含了很多测试工具包,如测试mapreduce系统读写文件系统,有testDFSIO工具 首先安装好hadoop,配置好环境变量 进入share目录下的mapreduce目录下面, ...
- Hadoop学习---Hadoop的HBase的学习
Hbase Hbase的特点: Hbase是bigtable的开源的仿制版本 建立在HDFS之上 可靠性,靠性能 大:一个表可以有上亿行,上百万列 面向列:面向列(族)的存储和权限控制,列(族)独立检 ...
- MR hadoop streaming job的学习 combiner
代码已经拷贝到了公司电脑的: /Users/baidu/Documents/Data/Work/Code/Self/hadoop_mr_streaming_jobs 首先是主控脚本 main.sh 调 ...
- MyBatis学习(一)---配置文件,Mapper接口和动态SQL
MyBatis MyBatis官方学习网站 http://www.mybatis.org/mybatis-3/zh/index.html 为什么需要MyBatis? Jdbc操作数据库的不足之处 1. ...
随机推荐
- 洛谷——P1104 生日
P1104 生日 题目描述 cjf君想调查学校OI组每个同学的生日,并按照从大到小的顺序排序.但cjf君最近作业很多,没有时间,所以请你帮她排序. 输入输出格式 输入格式: 有2行, 第1行为OI组总 ...
- 【解决问题】centOS 7 设置固定IP,无法上外网
使用Xenserver搭建服务器集群,在安装centOS时候,发现如果将服务器IP设置成为static ip,只能内网互通,无法上外网(ping www.baidu.com 失败) 网上搜索了一下,发 ...
- DHCP拒绝服务攻击工具DHCPig
DHCP拒绝服务攻击工具DHCPig DHCP服务负责网络的IP分配服务.通过攻击该服务,可以导致网络内主机获取不到IP,而无法正常使用网络.Kali Linux提供一款专用工具DHCPig.该工 ...
- POJ 2484 A Funny Game 博弈论 对称博弈
http://poj.org/problem?id=2484 1和2时Alice必胜,3时Bob必胜,其他情况下Bob只需要在Alice取过之后取一次将剩下的硬币链平均分为两份,然后Alice怎么取B ...
- Luogu P4093 [HEOI2016/TJOI2016]序列 dp套CDQ
题面 好久没写博客了..最近新学了CDQ...于是就来发一发一道CDQ的练习题 看上去就是可以dp的样子. 设\(dp_{i}\)为以i结尾的最长不下降序列. 易得:\(dp_{i}\)=\(max( ...
- 【数论】【Polya定理】poj1286 Necklace of Beads
Polya定理:设G={π1,π2,π3........πn}是X={a1,a2,a3.......an}上一个置换群,用m中颜色对X中的元素进行涂色,那么不同的涂色方案数为:1/|G|*(mC(π1 ...
- 【莫比乌斯反演+容斥】BZOJ2301-[HAOI2011]Problem b(成为权限狗的第一题纪念!)
[题目大意] 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. [思路] “怎么又是你系列……”思路 ...
- 鹦鹉学舌1——C语言初学者百题大战之三
#include<stdio.h> int main() { int a; scanf("%d",&a); printf("%d",a-a+ ...
- U-Boot添加menu命令的方法及U-Boot命令执行过程
转;http://chenxing777414.blog.163.com/blog/static/186567350201141791224740/ 下面以添加menu命令(启动菜单)为例讲解U-Bo ...
- windows 线程同步
Windows 临界区,内核事件,互斥量,信号量. 临界区,内核事件,互斥量,信号量,都能完成线程的同步,在这里把他们各自的函数调用,结构定义,以及适用情况做一个总结. 临界区: 适用范围:它只能同步 ...