Hadoop(十四)MapReduce 输入类InputFormat(切片)

文件切片

  • 什么是切片
    数据块(Block):HDFS中数据保存的单位,HDFS在物理上将数据分为一个一个Block管理
    数据切片(Split):在逻辑上对Map任务输入数据的切片。

  • 为什么要切片
    将输入文件分为多片可以并行进行Map阶段的计算,提高Job的运行速度。一份数据切片就会有一个MapTask。

  • 文件的切片机制 决定如何对数据文件进行切片,进而决定了一个MapReduce任务有多少个并行的MapTask
    简单的按照文件的内容长度切片,切片大小默认为Block的大小(128M),但每次切片完都会判断剩下的部分是否大于块的1.1倍,不大于1.1倍就归入上一个切片,数据切片只是对一个数据文件在逻辑上对输入进行分片,并不会在磁盘上将其切分成片进行存储。数据切片是MapReduce程序计算输入数据的单位,一个切片会对应启动一个MapTask。
    切片时不会考虑数据集整体,而是单独针对每一份文件切片(默认)。

一个完整的MapReduce程序包括四个阶段:Map Task阶段、Shuffle阶段、Reduce Task阶段 

InputFormat发生在MapTask之前。数据由InputFormat来负责进行切分和读取,然后将读取到的数据交给MapTask处理,所以InputFormat读取出来的数据是什么类型,MapTask接收的数据就是什么类型. 所以InputFormat是mapreduce处理数据的第一步,它接触的是最原始的数据文件,将原始数据处理成KV形式交给Mapper处理;

InputFormat是一个抽象类,用于获取Input输入数据,并将其切分和打成<k,v>键值对;这个类中有两个抽象方法,源码如下:

public abstract class InputFormat<K, V> {
    public InputFormat() {
    }
 
    public abstract List<InputSplit> getSplits(JobContext var1) throws IOException, InterruptedException;
 
    public abstract RecordReader<K, V> createRecordReader(InputSplit var1, TaskAttemptContext var2) throws IOException, InterruptedException;
}

(1)getSplits:负责将HDFS数据解析成InputSplit,也就是对原始数据进行切片,按照设定的切片大小进行逻辑切片;InputSplit只记录了切片的元数据信息,例如偏移量的起止位置、长度和所在节点列表等。决定如何对数据文件进行切片,进而决定了一个MapReduce任务有多少个并行的MapTask

(2)createRecordReader:获取每个InputSplit,并且将其中的每一行解析成<k,v>键值对。

FileInputFormat中默认的切片机制

切片的大小=块的大小=128M(如果程序运行在本地则是32M)切片的标准是看文件大的小是达到块大小的1.1倍(140.8M),如果达到则按128M进行切片,如果没达到,则其本身就是一个切片。切完第一片剩下的数据在进行比较,如果达到块大小的1.1被,依然按照128M切片,不够则本身为一个切片,以此类推。CombineTextInputFormat切片机制关于大量小文件的优化策略:默认情况下FileInputformat对任务的切片机制是按文件规划切片,不管文件多小,都会是一个单独的切片,都会交给一个maptask,这样如果有大量小文件,就会产生大量的maptask,处理效率极其低下

  • 切片时不考虑数据集整体,而是逐个针对每一一个文件单独切片

比如
1、MapReduce输入路径下假如有两个文件,分别是a.txt为320M, b.txt为10M大小
2、则经过FileInputFormat切片后产生的切片信息如下:
 

// 总产生4个切片,文件a有3个切片,文件b有1个切片
a.txt的切片1: 0~128M
a.txt的切片2: 128~256M
a.txt的切片3: 256~320M

b.txt的切片1:  0~10M

在MapReduce中,如果不指定,那么默认使用是TextInputFormat,而TextInputFormat继承了FileInputFormat。默认情况下,FileInputFormat负责对文件进行切片处理;TextInputFormat负责提供输入流来读取数据。

FileInputFormat在对文件进行切片过程中的注意问题:

a. 切片最小是1个字节大小,最大是Long.MAX_VALUE。

b. 如果是一个空文件,则整个文件作为一个切片来进行处理。

c. 在MapReduce中,文件存在可切与不可切的问题。大多数情况下,默认文件是可切的;但是如果是压缩文件,则不一定可切。

d. 如果文件不可切,无论文件多大,都作为一个切片来进行处理。

e. 在MapReduce中,如果不指定,Split和Block等大。

f. 如果需要调小Split,那么需要调小maxSize;如果需要调大Split,那么需要调大minSize。

g. 在切片过程中,需要注意阈值SPLIT_SLOP=1.1。

5. TextInputFormat在读取数据过程中需要注意的问题:

TextInputFormat在对文件进行处理之前,会先判断文件是否可切:先获取文件的压缩编码,然后判断压缩编码是否为空。如果压缩编码为空,则说明该文件不是压缩文件,那么默认可切;如果压缩编码不为空,则说明该文件是一个压缩文件,会判断这是否是一个可切的压缩文件。

在MapReduce中,默认只有BZip2(.bz2)压缩文件可切。

从第二个MapTask开始,会从当前切片的第二行开始处理,处理到下一个切片的第一行;第一个MapTask要多处理一行数据;最后一个MapTask要少处理一行数据。这样做的目的是为了保证数据的完整性。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Allen019

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值