MapReduce之InputFormat、OutputFormat(三)

文章目录

  • 1. 祝大家中秋节快乐
  • 2. MapReduce进阶
    • 2.1 MapReduce类型
    • 2.2 MapReduce输入格式
      • 2.2.1 InputFormat接口
      • 2.2.2 InputFormat接口的实现类
    • 2.3 MapReduce输出格式
      • 2.3.1 OutputFormat接口
      • 2.3.2 OutputFormat接口的实现类
  • 3. 小结

1. 祝大家中秋节快乐

身在长安,心在泰安,又是一年中秋佳节,相思之情,溢于言表。现留杜甫一诗与大家共勉。
今夜鄜州月,闺中只独看。
遥怜小儿女,未解忆长安。
香雾云鬟湿,清辉玉臂寒。
何时倚虚幌,双照泪痕干。

MapReduce之InputFormat、OutputFormat(三)_第1张图片

2. MapReduce进阶

2.1 MapReduce类型

  1. 输入数据类型由输入格式(InputFormat)设置,比如:TextInputFormat的Key类型为LongWritable,Value的类型是Text。
  2. map函数输出的Key类型通过setMapOutputKeyClass设置,Value类型通过setMapOutputKeyClass设置。
  3. reduce的输出的Key类型通过setOutputKeyClass设置,Value类型通过setOutputValueClass设置。

2.2 MapReduce输入格式

2.2.1 InputFormat接口

InputFormat类定义了如何分割和读取输入文件,它提供了以下功能:

  1. 选择作为输入的文件或对象。
  2. 定义把文件划分到任务的InputSplits。
  3. 为RecordReader读取文件提供一个工厂方法。
    InputFormat接口包含了以下两种方法:
 public abstract List<InputSplit> getSplits(JobContext context
                               ) throws IOException, InterruptedException;
                               
public abstract RecordReader<K,V> createRecordReader(InputSplit split,
                                         TaskAttemptContext context
                                        ) throws IOException, InterruptedException;

方法说明

getSplits(JobContext context)方法负责将一个大数据逻辑分成许多片,比如数据库表有100条数据,按照主键ID升序存储,假设每20条分成一片,这个List的大小就是5,然后每个InputSplit记录两个参数,第一个为这个分片的起始ID,第二个为这个分片数据的大小,这里是20。很明显InputSplit并没有真正存储数据,只是提供了一个如何将数据分片的方法。

createRecordReader方法,根据定义,返回一个能够读取分片记录的RecordReader。getSplit用来获取由输入文件计算出来的InputSplit,后面计算InputSplit时,会考虑输入文件是否可分割、文件存储时分块的大小和文件大小等因素;而createRecordReader()方法提供了RecordReader的实现,将key-value对从InputSplit中正确读出来,比如LineRecordReader,它是以偏移值为Key,每行的数据为Value,这使所有createRecordReader()返回LineRecordReader的InputFormat都是以偏移值为Key、每行数据为Value的形式读取输入分片的。

2.2.2 InputFormat接口的实现类

InputFormat接口实现类有很多,其层次结构如下所示:

MapReduce之InputFormat、OutputFormat(三)_第2张图片常用的实现类介绍:

  1. FileInputFormat
    FileInputFormat是所有使用文件作为其数据源的InputFormat实现的基类,它的主要作用是指出作业的输入文件位置。因为作业的输入被设定为一组路径,这对指定作业输入提供了很强的灵活性。FileInputFormat提供了四种静态方法来设定作业的输入路径:
public static void addInputPaths(Job job, String commaSeparatedPaths)
public static void addInputPath(Job job, Path path)
public static void setInputPaths(Job job, Path... inputPaths)
public static void setInputPaths(Job job, String commaSeparatedPaths)
  1. KeyValueTextInputFormat
    每一行均为一条记录,被分隔符(缺省是tab)分割为key(Text),value(Text),当然分隔符可以自己设定。
  2. TextInputFormat
    默认的输入格式是TextInputFormat,它把输入文件每一行作为单独的一个记录,但不做解析处理,这对那些没有被格式化的数据或是基于行的记录来说是很有用的,比如日志文件。

2.3 MapReduce输出格式

2.3.1 OutputFormat接口

OutputFormat接口主要用于描述输出数据的格式,它能够将用户提供的key/value对写入特定格式的文件中。其功能与前面描述的InputFormat相似,Hadoop提供的OutputFormat实例会把文件写在本地磁盘或HDFS上。每一个reducer会把结果输出写在公共文件夹中一个单独的文件内。这些文件一般命名为:part-xxxxx,而xxxxx是关联到某个reduce任务的partition的id。

2.3.2 OutputFormat接口的实现类

下图为OutputFormat接口的实现类层次图:
MapReduce之InputFormat、OutputFormat(三)_第3张图片常用的OutputFormat实现类的介绍:

  1. 文本输出
    默认的输出格式是TextOutputFormat,它把每条记录写为文本行。它的键和值可以实现Writable的任意类型,因为TextOutputFormat调用toString()方法把他们转换为字符串。每一个key/value键值对都以制表符为分隔符,当然也可以自行设定(mapreduce.output.textoutputfomat.separator),与FileOutputFormat对应的输入格式是KeyValueTextInputFormat,它可以通过配置分隔符将key/value进行文本分割。
    同时,可以使用NullWritable来省略输出的key或value,或者两个都省略,相当于NullOutputFormat的输出格式,这也会导致无分隔符的输出,以使输出适合用TextInputFormat读取。
  2. 二进制输出
    SequenceFileOutputFormat将它的输出写为一个顺序文件。如果输出需要作为后续的MapReduce任务的输入,这便是一种合适的输出格式,可以通过快速的序列化任意的数据类型到文件中,而对应SequenceFileInputFormat则会把文件反序列化为相同类型并提交到下一个Mapper的输入数据。

3. 小结

下期预告以及下下期预告:

  1. Combiner详细解析及操作
  2. Partitioner详细解析及操作
  3. RecordReader详细解析及操作

你可能感兴趣的:(大数据,#,MapReduce)