MapReduce 框架原理



1.InputFormat可以对Mapper的输入进行控制

2.Reducer阶段会主动拉取Mapper阶段处理完的数据

3.Shuffle可以对数据进行排序、分区、压缩、合并,核心部分。

4.OutPutFomat可以对Reducer的输出进行控制

1 InputFormat数据输入

1.1 切片与MapTask并行度决定机制

MapTask:负责 Map 阶段的整个数据处理流程。

MapTask进程对每一个<K,V>调用一次map()方法

MapTask并行度:一次用几个MapTask进程对数据进行处理

问题引出

MapTask的并行度决定Map阶段的任务处理并发度,进行影响整个Job的处理速度。

思考:1G的数据,启动8个MapTask,可以提高集群的并发处理能力。

MapTask的个数是越多越好吗?不是,根据数据的大小决定。不然开启的MapTask的时间比处理数据的时间还长

哪些因素会影响MapTask并行度?

MapTask并行度决定机制

数据块:Block是HFDS物理上把数据分成一块一块。数据块是HDFS存储数据单位

数据切片:只是在逻辑上对输入进行分片,并不会在磁盘上讲其切分粗存储。数据切片是MapReduce程序计算输入数据的单位,一个切片会对应启动一个MapTask

Job提交流程源码

添加断点,开始debug

进入waitForCompletion()方法

先执行一行到submit()方法,再进入submit()方法

这个submit()方法就是我们需要关注的地方

waitForCompletion()
submit();
// 1 建立连接
connect();
// 1)创建提交 Job 的代理
new Cluster(getConfiguration());
// (1)判断是本地运行环境还是 yarn 集群运行环境
initialize(jobTrackAddr, conf); // 2 提交 job
submitter.submitJobInternal(Job.this, cluster)
// 1)创建给集群提交数据的 Stag 路径
Path jobStagingArea = JobSubmissionFiles.getStagingDir(cluster, conf);
// 2)获取 jobid ,并创建 Job 路径
JobID jobId = submitClient.getNewJobID();
// 3)拷贝 jar 包到集群
copyAndConfigureFiles(job, submitJobDir);
rUploader.uploadFiles(job, jobSubmitDir);
// 4)计算切片,生成切片规划文件,向stag路径写切片文件
writeSplits(job, submitJobDir);
maps = writeNewSplits(job, jobSubmitDir);
input.getSplits(job);
// 5)向 Stag 路径写 XML 配置文件
writeConf(conf, submitJobFile);
conf.writeXml(out);
// 6)提交 Job,返回提交状态
status = submitClient.submitJob(jobId, submitJobDir.toString(),job.getCredentials());

断点1:连接客户端,有Yarn客户端和本地客户端YarnClinetProtocolProvide@1832、LocalClinetProtocolProvide@1888

断点2:向集群提交job信息,提交的内容:1.整个job运行需要的参数信息.xml 2.切片信息 3.jar包 如果是本地,不会提交jar包。如果是集群模式会提交jar包。

提交完之后,jobState变成了RUNNING,后面监控并打印job信息,提交完毕删除缓存信息(切片信息与该job需要的参数信息)

切片源码

每个文件都会单独切片。切割之前先确定文件是否可以切割。

切片的大小

块的大小是不变的,通过改变另外两个变量的大小改变切片大小

//默认值 :minSize=1 maxSize=long类型的最大值
long splitSize = computeSplitSize(blockSize,minSize,maxSize);
computeSplitSize(Math.max(minSize,Math.min(maxSize,blocksize)))

切片的大小如果在本地默认是32M,那么32.1的文件需要切成两片吗?不需要,1.1倍的膨胀范围。0.11.1<321.1,所以切一片就行了。

1.2 FileInputFormat切片机制

1.简单地按照文件的内容长度进行切片

2.切片大小,默认等于BlockSize大小

3.切片时不考虑数据集整体,逐个针对每个文件进行切片

切片流程

  1. 程序先找到输入的数据目录
  2. 开始遍历处理目录下的每一个文件,对每一个文件进行单独的切片(FileInputformat切片规则)
  3. 遍历第一个文件ranan.txt

    3.1 获取文件大小fs.sizeOf(ranan.txt)

    3.2 计算切片大小

    computeSplitSize(Math.max(minSize,Math.min(maxSize,blocksize)))

    3.3 默认情况下切片大小=块大小

    3.4 每次切片时,需要判断剩下的部分是不是大于块的1.1倍,大于就再继续切片,小于剩下的部分就是一块。(源码知识点)

    3.5 将切片信息写到一个切片规划文件中

    3.6 整个切片的核心过程在getSplit()方法中完成

    3.7 InputSplit只记录了切片的元数据信息,比如起始位置、长度,以及所在的节点列表等。逻辑切片
  4. 提交切片规划文件到YARN上(Job提交),YARN上的MrAppMaster就可以根据切片规划文件计算开启的MapTask个数

1.3 TextInputFormat切片机制

TextInputFormat是FileInputFormat的实现类。输入的key是偏移量,value是一行内容

  • FileInputFormat

    • TextInputFormat 默认实现类
    • CombineFileInputFormat
      • CombineTextInputFormat
    • NLineInputFormat

思考

在运行MapReduce程序时,输入的文件格式包括:基于行的日志文件、二进制格式文件、数据库表等。那么针对不同的数据类型,MapReduce是如何读取这些数据的呢?

FileInputFormat常见的接口实现类包括:TextInputFormat、keyValueTextInputFormat、NLineInputFormat、CombineTextInputFormat和自定义InputFormat等。

//输入是偏移量,输出是每行内容
class TextInputFormat extends FileInputFormat<LongWritable,Text>
//按分隔符切,左边的是key右边的是value
class KeyValueTextInputFormat extends FileInputFormat<Text,Text>
//一次性读取多行统一处理
class NLineInputFormat extends FileInputFormat<LongWritable,Text>
//一次读取多个文件,一起处理
class CombineTextInputFormat extends CombineFileInputmat<LongWritable,Text>

1.4 CombineTextInputFormat切片机制

应用场景

框架默认的TextInputFormat切片机制是对任务按文件规划切片,不管文件多小,都会是一个单独的切片,如果有大量的小文件,就会产生多个MapTask,处理效率极其低下。

用于小文件多的场景,可以将多个小文件从逻辑上规划到一个切片种,这样就只用开启一个MapTask处理。

虚拟存储切片最大值设置

虚拟存储切片最大值设置最好根据实际的小文件大小情况来设置具体的值。

//4m
CombineTextInputFormat.setMaxInputSplitSize(job,4194304)

最终存储文件的顺序按文件名称的字典顺序排序

1.5 案例实操

需求

将输入的小文件合并成一个切片处理

输入数据D:\hadoop_data\input\inputcombinetextinputformat

期望:期望一个切片处理4个文件

实现过程

1.使用之前的WordCount程序,观察到切片数个数为4

新建combinetextinputformat包,复制之前的WordCount程序

修改WordCountDriver的输入路径,其余不做修改。

没有修改切片规则,默认按照TextInputFormat切片规则切片,对每一个文件单独切片

2.在WordCountDriver种增加如下代码,观察到切片个数为3

// 如果不设置 InputFormat,它默认用的是 TextInputFormat.class
job.setInputFormatClass(CombineTextInputFormat.class);
//虚拟存储切片最大值设置 4m
CombineTextInputFormat.setMaxInputSplitSize(job, 4194304);

3.在WordCountDriver种增加如下代码,观察到切片个数为1

// 如果不设置 InputFormat,它默认用的是 TextInputFormat.class
job.setInputFormatClass(CombineTextInputFormat.class);
//虚拟存储切片最大值设置 20m
CombineTextInputFormat.setMaxInputSplitSize(job, 20971520);

MapReduce03 框架原理InputFormat数据输入的更多相关文章

  1. MapReduce框架原理-InputFormat数据输入

    InputFormat简介 InputFormat:管控MR程序文件输入到Mapper阶段,主要做两项操作:怎么去切片?怎么将切片数据转换成键值对数据. InputFormat是一个抽象类,没有实现怎 ...

  2. 模拟Select-Options对象实现多项数据输入功能

       模拟Select-Options对象实现多项数据输入功能 Select-Options对象可以同时输入多项值并将所输入数据存入内表以供程序使用,不过Select-Options的功能有一定的局限 ...

  3. Web 软件测试 Checklist 应用系列,第 1 部分: 数据输入

    Web 软件测试 Checklist 应用系列,第 1 部分: 数据输入 本文为系列文章"Web 软件测试 Checklist 应用系列"中的第一篇.该系列文章旨在阐述 Check ...

  4. JAVA用户数据输入

    数据输入 首先需要导入扫描仪 然后声明扫描仪 输出输入提示 接收用户数据的数据 输出用户数据的数据 实例: import java.util.Scanner; //导入扫描仪 public class ...

  5. Python学习教程(learning Python)--1.3 Python数据输入

    多数应用程序都有数据输入语句,用于读入数据,和用户进行交互,在Python语言里,可以通过raw_input函数实现数据的从键盘读入数据操作. 基本语法结构:raw_input(prompt) 通常p ...

  6. 【C语言】-数据输入-scanf( )和getchar( )

    格式化输入函数scanf( ) scanf( )功能: 按照指定的格式读入键盘上输入的若干个任意类型的数据,存入到argument参数所指向的内存单元,函数返回值为读入并赋给argument的数据个数 ...

  7. Java基础知识强化之IO流笔记57:数据输入输出流(操作基本数据类型)

    1. 数据输入输出流(操作基本数据类型) (1)数据输入流:DataInputStream DataInputStream(InputStream in) (2)数据输出流:DataOutputStr ...

  8. ACM 关于数据输入加速

    转载请注明出处:http://blog.csdn.net/a1dark 分析:我们都知道运行时间对我们来说很重要.有时候不惜用大量的内存去换取一点时间.有些人可能都比较关注这个问题.首先时间上:cin ...

  9. C语言数据输入与输出

    1 概论 C语言提供了跨平台的数据输入输出函数scanf()和printf()函数,它们可以按照指定的格式来解析常见的数据类型,例如整数,浮点数,字符和字符串等等.数据输入的来源可以是文件,控制台以及 ...

随机推荐

  1. Python 模块 itertools

    python 2.6 引入了itertools模块,使得排列组合的实现非常简单: import itertools 有序排列:e.g., 4个数内选2个排列: >>> print l ...

  2. ADB WIFI无线调试真正摆脱usb数据线连接,一次也不用!

    常见的使用ADB无线调试步骤 手机"开发者模式"菜单中开启"USB调试" 和"无线调试",手机网络与电脑在同一网内; 手机使用USB与电脑进 ...

  3. JuiceFS CSI Driver 的最佳实践

    文章根据 Juicedata 工程师朱唯唯,在云原生 Meetup 杭州站所作主题演讲<JuiceFS CSI Driver 的最佳实践>整理而成. 大家好,我是来自 Juicedata ...

  4. httprunner3源码解读(3)client.py

    源码目录结构 ApiResponse 这个类没啥好说的 class ApiResponse(Response): """ 继承了requests模块中的Response类 ...

  5. 使用Netty和动态代理实现一个简单的RPC

    RPC(remote procedure call)远程过程调用 RPC是为了在分布式应用中,两台主机的Java进程进行通信,当A主机调用B主机的方法时,过程简洁,就像是调用自己进程里的方法一样.RP ...

  6. v-bind使用

    v-bind基本使用 动态地绑定一个或多个属性,或者绑定一个组件 prop 到表达式. 语法:v-bind:属性名 = 属性值 <!-- 绑定一个 attribute --> <im ...

  7. 删除html标签,取其中的文本

    public String removeHtmlTags() { String str = "<p><b> welcome to test</b>< ...

  8. nio实现文件夹内容的监听

    参考的博客 package com.jp.filemonitor; import java.io.IOException; import java.nio.file.FileSystems; impo ...

  9. vm扩展磁盘容量后不能启动

    主要原因是,新添加的磁盘空间没有分配,系统识别不出来,导致不能开机. 解决方法: 找到虚拟机的文件路径地址,默认是C:\Users\用户名\Documents\Virtual Machines\Cen ...

  10. celery tasks always in pending

    Result backend doesn't work or tasks are always in PENDING state¶All tasks are PENDING by default, s ...