一、输入格式关系

image.png

二、切片机制(任务整体读取数据)

切片机制在两个抽象类中实现,分别是FileInputFormat和CombineTextInputFormat

1.FileInputFormat 切片机制

  1. 简单的按照文件的内容长度进行切片
  2. 切片大小默认等于block大小
  3. 切片时不考虑数据集整体,而是针对每一个文件单独切片
  4. 重写isSplitable()方法可以不进行分片

    2.CombineTextInputFormat 切片机制

    框架默认使用TextInputFormat进行切片,在存在大量小文件的情况下会产生大量的MapTask任务,处理效率比较低。通过实现CombineTextInputFormat的抽象方法getRecordReader()可以将小文件聚合成一个大切片以提高效率。

    三、Mapper读取数据

    1.FileInputFormat实现类

  • TextInputFormat
    • 默认的FileInputFormat实现类
    • 按行读取每个分片记录
    • 输入:。LongWritable:该行在整个文件中的起始字节偏移量;Text:改行的内容。
  • KeyValueTextInputFormat
    • 每一行均为一条记录
    • 设置分割符分割为key和value
    • 输入:。两个Text分别为分割符分割的key和value
  • NLineInputFormat
    • 不在按照Block来划分InputSplit,而是按照NLineInputFormat指定的N行数来划分
    • 输入和FileInputFormat类似,但一个MapTask只接收数量<=N的行数

      2.自定义InputFormat

      需求:将多个小文件合并成为一个SequenceFile文件
      流程如下:
  1. 自定义一个类继承FileInputFormat
    1. 重写isSplitable()方法,返回false不可切割
    2. 重写createRecordReader(),创建自定义的RecordReader对象,并初始化
  2. 改写RecordReader,实现一次读取一个完整文件封装为KV
    1. 使用IO流一次读取一个文件输出到value中,因为设置了不可切片,最终把所有文件都封装到value中
    2. 获取文件路径信息+名称,并设置key
  3. 设置Driver
    1. 设置输入的InputFormat
    2. 设置输出的OutputFormat为SequenceFileOutPutFormat