使用Hadoop OutputFormat输出格式

我们可以使用Hadoop OutputFormat接口来定义数据存储格式、数据存储位置、以及组织MapReduce计算的输出数据。一个OutputFormat准备输出位置并提供一个RecordWriter实现来执行实际的序列化和存储数据。Hadoop OutputFormat决定如何使用RecordWriter实现将输出写入输出文件。

在本节中,我们将看到什么是Hadoop输出格式,什么是Hadoop RecordWriter,以及如何在Hadoop中使用RecordWriter。另外,我们还将了解Hadoop中各种类型的输出格式,如TextOutputFormat、SequenceFileOutputFormat、MapFileOutputFormat、SequenceFileAsBinaryOutputFormat、DBOutputFormat、LazyOutputFormat和MultipleOutputs。

RecordWriter

正如我们所知,Reducer将Mapper生成的中间key-value对集合作为输入,并对它们运行reduce函数来生成同样是0个或多个key-value对的输出。

RecordWriter将这些输出key-value对从Reducer阶段写到输出文件中。

Hadoop输出格式

Hadoop RecordWriter从Reducer获取输出数据,并将这些数据写到输出文件中。这些输出键值对被RecordWriter写入输出文件的方式由输出格式决定。OutputFormat和InputFormat函数类似。Hadoop提供的OutputFormat实例用于写入HDFS或本地磁盘上的文件。OutputFormat描述了Map-Reduce作业的输出规范。根据输出规范:

  • MapReduce作业检查输出目录是否已经存在。
  • OutputFormat提供用于写作业输出文件的RecordWriter实现。输出文件存储在文件系统中。

FileOutputFormat.setOutputPath()方法用于设置输出目录。每个Reducer在一个公共输出目录中写入一个单独的文件。

Hadoop输出格式的类型

Hadoop OutputFormat有多种类型,FileOutputFormat是用于所有基于文件的输出格式的基类。

  • TextOutputFormat。Hadoop使用org.apache.hadoop.mapreduce.lib.output.TextOutputFormat<K,V>抽象类作为MapReduce计算的默认OutputFormat。 TextOutputFormat将输出数据的(key,value)对写入到HDFS中的普通文本文件,每个(key,value)对一行。 TextOutputFormat使用tab制表符来分隔一个record中的key和value,可以使用mapreduce.output.textoutputformat.separator属性进行更改。 key和value可以是任何类型,因为TextOutputFormat通过调用toString()将它们转换为字符串。
  • SequenceFileOutputFormat。它是一种输出格式,用于写序列文件的输出,它是MapReduce作业之间的中间格式,可快速将任意数据类型序列化到文件中。 压缩由SequenceFileOutputFormat上的静态方法控制。
  • SequenceFileAsBinaryOutputFormat。它是SequenceFileInputFormat的另一种形式,它将key和value写入二进制格式的序列文件。
  • MapFileOutputFormat。它是Hadoop输出格式中FileOutputFormat的另一种形式,用于将输出作为map file写入。 MapFile中的key必须按顺序添加,所以我们需要确保reducer按已排序的顺序发出key。
  • MultipleOutputs。它允许将数据写入文件,这些文件的名称来自于输出键和值,或者实际上来自于任意字符串。
  • LazyOutputFormat。有时FileOutputFormat将创建输出文件,即使它们是空的。 LazyOutputFormat是一个包装器OutputFormat,它确保仅在为给定分区发出记录时才创建输出文件。 Hadoop中的DBOutputFormat是一种输出格式,用于向关系数据库和HBase写入数据。它将reduce输出发送到一个SQL表。
  • DBOutputFormat。它接受key-value对,其中key继承自DBwritable的类型。返回的RecordWriter通过批处理SQL查询仅将key写入数据库。

SequenceFileOutputFormat

下面的步骤演示了怎样使用基于FileOutputFormat的SequenceFileOutputFormat作为用于Hadoop MapReduce计算的OutputFormat。

1)使用Job对象指定org.apache.hadoop.mapreduce.lib.output.SequenceFileOutputFormat<K,V>作为用于Hadoop MapReduce计算的OutputFormat:

Job job = ……
……
job.setOutputFormatClass(SequenceFileOutputFormat.class);

2)设置job的输出路径:

FileOutputFormat.setOutputPath(job, new Path(outputPath));

说明:

SequenceFileOutputFormat序列化数据到Hadoop SequenceFiles。Hadoop SequenceFiles将数据作为二进制的key-value对存储,并支持数据压缩。SequenceFiles用于存储非文本数据特别有效。我们可以使用SequenceFiles来存储一个MapReduce计算的结果,如果该输出将被用作另一个Hadoop MapReduce计算的输入的话。

SequenceFileOutputFormat基于FileOutputFormat,FileOutputFormat是用于基于文件的OutputFormat的基类。因此,我们使用FileOutputFormat的setOutputPath()方法来指定MapReduce计算的输出路径。当使用基于FileOutputFormat的任何OutputFormat时,必须执行这一步。

FileOutputFormat.setOutputPath(job, new Path(outputPath));

我们可以通过继承org.apache.hadoop.mapreduce.OutputFormat<K,V>抽象类来实现自定义的OutputFormat类,以写出MapReduce计算的输出,以专有的或自定义的数据格式和/或存储结果到HDFS之外的存储中。在我们自己的OutputFormat实现存储数据到一个文件系统中时,可以从FileOutputFormat类继承。



《Flink原理深入与编程实战》