码迷,mamicode.com
首页 > 其他好文 > 详细

Hadoop2.6.0学习笔记(六)TextOutputFormat及RecordWriter解析

时间:2015-12-03 15:47:51      阅读:510      评论:0      收藏:0      [点我收藏+]

标签:hadoop outputformat

鲁春利的工作笔记,谁说程序员不能有文艺范?



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解析

标签:hadoop outputformat

原文地址:http://luchunli.blog.51cto.com/2368057/1719174

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!