前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MapReduce原理分析之MapTask读取数据

MapReduce原理分析之MapTask读取数据

作者头像
用户4919348
发布2019-04-17 14:51:23
4940
发布2019-04-17 14:51:23
举报
文章被收录于专栏:波波烤鸭波波烤鸭

  通过前面的内容介绍相信大家对于MapReduce的操作有了一定的了解,通过客户端源码的分析也清楚了split是逻辑分区,记录了每个分区对应的是哪个文件,从什么位置开始到什么位置介绍,而且一个split对应一个Map Task任务,而MapTask具体是怎么读取文件的呢?本文来具体分析下。

MapTask读取数据的过程

  我们要分析的就是如下的过程:

在这里插入图片描述
在这里插入图片描述

1.自定义Mapper

  在自定义的Mapper中我们只需要重写map方法,那么每读取一行记录就会调用一次该方法,如下

在这里插入图片描述
在这里插入图片描述

2.查看Mapper源码

代码语言:javascript
复制
public class Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT> {

  public abstract class Context
    implements MapContext<KEYIN,VALUEIN,KEYOUT,VALUEOUT> {
  }
  protected void setup(Context context
                       ) throws IOException, InterruptedException {
    // NOTHING
  }
  @SuppressWarnings("unchecked")
  protected void map(KEYIN key, VALUEIN value, 
                     Context context) throws IOException, InterruptedException {
    context.write((KEYOUT) key, (VALUEOUT) value);
  }

  protected void cleanup(Context context
                         ) throws IOException, InterruptedException {
    // NOTHING
  }
  
  public void run(Context context) throws IOException, InterruptedException {
    setup(context);
    try {
      while (context.nextKeyValue()) {
        map(context.getCurrentKey(), context.getCurrentValue(), context);
      }
    } finally {
      cleanup(context);
    }
  }
}

通过源码我们能够看到里面的方法如下

方法

说明

setup

任务开始的时候执行一次,可以做一些预处理操作

map

每读取一行记录执行一次,获取KV对

cleanup

任务结束前执行一次,可以做一些收尾工作,比如setup的时候声明一个变量sum,map阶段累加,最后在cleanup的时候将sum输出,获取统计的结果

run

当于map task的驱动,将前面的方法组成了一个模板

3.context.nextKeyValue()

  context的类型是Context实现了MapContext

代码语言:javascript
复制
  public abstract class Context
    implements MapContext<KEYIN,VALUEIN,KEYOUT,VALUEOUT> {
  }

  MapContext的实现类是MapContextImpl

在这里插入图片描述
在这里插入图片描述

  而nextKeyValue()方法的调用

在这里插入图片描述
在这里插入图片描述

说明调用的是RecordReader中的方法,而具体是RecordReader中的哪个实现类呢?继续往下。

4.FileInputFormat

  我们在启动类中设置了输入输出路径。进入FileInputFormat的子类TextFileInputFormat中查看

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  说明nextKeyValue()其实执行的是RecordReader中的nextKeyValue方法。

在这里插入图片描述
在这里插入图片描述

读取split文件中每行数据的方法。将每行的偏移量保存在key中,每行的具体数据保存在value中,分别通过getCurrentKey方法和getCurrentValue方法来获取。

代码语言:javascript
复制
 public boolean nextKeyValue() throws IOException {
    if (key == null) {
      key = new LongWritable();
    }
    key.set(pos);
    if (value == null) {
      value = new Text();
    }
    int newSize = 0;
    // We always read one extra line, which lies outside the upper
    // split limit i.e. (end - 1)
    while (getFilePosition() <= end || in.needAdditionalRecordAfterSplit()) {
      if (pos == 0) {
        newSize = skipUtfByteOrderMark();
      } else {
        newSize = in.readLine(value, maxLineLength, maxBytesToConsume(pos));
        pos += newSize;
      }

      if ((newSize == 0) || (newSize < maxLineLength)) {
        break;
      }

      // line too long. try again
      LOG.info("Skipped line of size " + newSize + " at pos " + 
               (pos - newSize));
    }
    if (newSize == 0) {
      key = null;
      value = null;
      return false;
    } else {
      return true;
    }
  }

自此我们简单的分析了下map具体是怎么一行一行的读取数据的了。MapReduce的其他阶段我们后续再慢慢分析

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年04月06日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • MapTask读取数据的过程
    • 1.自定义Mapper
      • 2.查看Mapper源码
        • 3.context.nextKeyValue()
          • 4.FileInputFormat
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档