鲁春利的工作笔记,谁说程序员不能有文艺范?
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