MapReduce(五)——切片机制之TextInputFormat与CombineTextInputFormat

TextInputFormat切片机制

TextInputFormat是FileInputFormat的若干个实现类之一。

首先,要明确的是,TextInputFormat在切片时不考虑数据集整体,也就是不考虑输入路径下其他文件,而是逐个对每一个文件单独切片。

它在读取单个文件数据时是按行读取的,其用来存储读取的数据的数据结构固然是键值对,键存储的是该行在整个文件中的起始字节的偏移量,键的数据类型是LongWritable。而值是这行的内容,不包括任何的行终止符,即换行符和回车符,值的数据类型是Text。下面给一个例子

#文本内容

abc def ghi

hello world

Sadge Sadge Sadge

#键值对内容

< 0, abc def ghi >

< 13, hello world >

< 26, Sadge Sadge Sadge>

以上便是很常见的TextInputFormat,同时也是框架默认选择切片策略,接下来会说明一下CombineTextInputFormat。

CombineTextInputFormat切片机制

如果对每个文件都单独做一个切片然后再开启MapTask,那么如果面临过多的小文件时,比如1万个1kb的小文件,那么显然再用这种一个文件一个片的策略有些过于愚蠢了,要为每一个小文件都花上大量的资源去开启一个Task。

这个时候就需要在逻辑上对小文件进行合并,然后再做切片处理,CombineTextInputFormat的切片策略就是这样。CombineTextInputFormat可以将许多小文件在逻辑上规划到一个切片中,然后这样一个MapTask就可以一起处理多个小文件了。

接下来说明一下CombineTextInputFormat的切片流程。

它的切片流程略微复杂一些,其可以划分为两部分,虚拟存储过程和切片合并过程。

在切片前,开发者会设定好一个虚拟存储切片最大值,具体代码会在后面一起说明,而这个值设置多少最好根据文件实际情况来判断设置多少。

对一列文件,先拆分文件,目的是将拆成小文件,当然这个过程是虚拟的,是通过操作索引来完成的。

拆分策略是这样的,如果这个文件大于两倍的最大值(虚拟存储切片最大值),那么就先切出来一份最大值大小的片。如果这个文件大于一倍的最大值,但小于两倍,那么就均分这个文件(从中间劈开),目的是防止出现零头的情况。小于一倍的不切。那么这就是拆分过程。

这个时候问题就来了,如果全称这么做,文件会不会太碎了。然后这个时候第二个过程就起作用了。即将虚拟文件大小按顺序前后相加。看是否大于最大值,一旦大于,那么将这几个虚拟文件作为一个切片,如果不大于,那么则继续加上下一个虚拟存储文件,并形成一个切片。

来一个例子

最大值为4M,比如说有文件大小

1.5M  6.2M  7.8M  4.2M  1M。

那么第一个过程之后

1.5M 3.1M 3.1M 3.9M 3.9M 2.1M 2.1M 1M

第二个过程则是

(1.5M 3.1M)(3.1M 3.9M)(3.9M 2.1M)(2.1M 1M)

划分完毕

CombineTextInputFormat实现

在之前编写的Driver的main中,在提交job前的地方添加如下代码

// 默认用的是TextInputFormat.class
job.setInputFormatClass(CombineTextInputFormat.class);

// 根据需要改成需要的值,这里虚拟存储切片最大值设置的是4M
CombineTextInputFormat.setMaxInputSplitSize(job, 4194304);
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值