鲁春利的工作笔记,谁说程序员不能有文艺范?
MapReduce提供了许多默认的输出格式,如TextOutputFormat、KeyValueOutputFormat等。MapReduce中输出文件的个数与Reduce的个数一致,默认情况下有一个Reduce,输出只有一个文件,文件名为part-r-00000,文件内容的行数与map输出中不同key的个数一致。如果有两个Reduce,输出的结果就有两个文件,第一个为part-r-00000,第二个为part-r-00001,依次类推。
MapReduce中默认实现输出功能的类是TextOutputFormat,它主要用来将文本数据输出到HDFS上。
public class TextOutputFormat<K, V> extends FileOutputFormat<K, V> {
public static String SEPERATOR = "mapreduce.output.textoutputformat.separator";
// 定义了内部类用来实现输出,换行符为\n,分隔符为\t(可以通过参数修改)
protected static class LineRecordWriter<K, V> extends RecordWriter<K, V> {
public LineRecordWriter(DataOutputStream out) { // 实际为FSDataOutputStream
this(out, "\t");
}
/** 主要的结构就是两个方法:write和close **/
public synchronized void write(K key, V value)throws IOException {
boolean nullKey = key == null || key instanceof NullWritable;
boolean nullValue = value == null || value instanceof NullWritable;
if (nullKey && nullValue) {
return;
}
if (!nullKey) {
writeObject(key); // 将Text类型数据处理成字节数组
}
if (!(nullKey || nullValue)) {
out.write(keyValueSeparator);
}
if (!nullValue) {
writeObject(value);
}
out.write(newline); // 换行(newline = "\n".getBytes(utf8);)
}
public synchronized void close(TaskAttemptContext context) throws IOException {
out.close();
}
}
// 内部类定义结束,下面为TextOutputFormat唯一的关键方法
public RecordWriter<K, V> getRecordWriter(TaskAttemptContext job)
throws IOException, InterruptedException {
// 1、根据Configuration判定是否需要压缩,若需要压缩获取压缩格式及后缀;
// 2. 获取需要生成的文件路径,getDefaultWorkFile(job, extension)
// 3. 根据文件生成FSDataOutputStream对象,并return new LineRecordWriter。
}
}通过TextFileOutput类分析出具体需要将数据保存到HDFS的什么位置上,是通过FileOutputFormat类的getDefaultWorkFile方法来获取的。实际上对于MapReduce中所有的输出都需要继承OutputFormat,先看一下OutputFormat的类定义。
/**
* OutputFormat定义了Map-Reduce作业的输出规范,如:
* 1、校验,如指定的输出目录是否存在,输出的空间是否足够大;
* 2、指定RecordWriter来将MapReduce的输出写入到FileSystem(一般为HDFS);
*/
public abstract class OutputFormat<K, V> {
// 获取与当前task相关联的RecordWriter对象
public abstract RecordWriter<K, V> getRecordWriter(TaskAttemptContext context)
throws IOException, InterruptedException;
// 当提交job时检查当前job的输出规范是否有效,如输出目录是否已存在等
public abstract void checkOutputSpecs(JobContext context)
throws IOException, InterruptedException;
// Get the output committer for this output format.
// This is responsible for ensuring the output is committed correctly.
public abstract OutputCommitter getOutputCommitter(TaskAttemptContext context)
throws IOException, InterruptedException;
}在TextOutputFormat中实现了getRecordWriter,而TextOutputFormat的是FileOutputFormat的子类,而FileOutputFormat是的子类。
本文出自 “闷葫芦的世界” 博客,请务必保留此出处http://luchunli.blog.51cto.com/2368057/1719174
Hadoop2.6.0学习笔记(六)TextOutputFormat及RecordWriter解析
原文:http://luchunli.blog.51cto.com/2368057/1719174