Apache Hadoop MapReduce Mapper类小解

1.MapperTask

如果不考虑shuffle阶段的话,mapreduce程序主要分为两个大的模块,即Mapper模块和Reduce模块,而其中Mapper模块对应的是一个个maptask,而每一个MapperTask任务,对应于每一个逻辑切片(split)。因此了解Mapper运行流程很重要。

2.Mapper类 简介

我们要进行mapreduce编程那么就要自定义实现Mapper和Reducer,其中自定义实现Mapper类的话,就必须继承Mapper接口

1) 类的定义
public class Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT>

Mapper类定义使用了类上泛型。

KEYIN: 框架底层提供的类型,表示输入文件行首偏移量类型,即long类型,对应序列化类型为LongWritable

VALUEIN:框架底层提供的类型,表示输入文件行内容类型,即String类型,对应序列化类型为Text

KEYOUT:mapper向下一层传递的key的类型,默认作为分区排序分组的参考字段,可以自定义

VALUEOUT: mapper向下一层传递的value的类型,如前面WordCount案例中的单词个数定义为IntWritable类型,即int类型的序列化类型。

2)类上序列化类型
LongWritable     //  对应java中long类型的序列化类型
IntWritable      //  对应于java中int类型的序列化类型
Text             //  对应于Java中String类型的序列化类性
NullWritable     //  对应于java中null的序列化类型
.......

对于分布式计算来说,数据在网络间传输是很频繁的,使用java自带的Serializable接口非常消耗性能,hadoop默认采用Writable接口以替换该接口,其只会序列化对应的字段,而不会序列化整个类的结构。

3.Mapper类方法分析
1)mappertask默认调用的方法
public void run(Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT>.Context context) throws IOException, InterruptedException {
    // 一般用来进行初始化操作或者配置
    this.setup(context);
    try {
        while(context.nextKeyValue()) {
            this.map(context.getCurrentKey(), context.getCurrentValue(), context);
        }
    } finally {
        //一般用来进行资源是释放等操作
        this.cleanup(context);
    }

}

每执行一个maptask,必定调用run方法。而从run方法调用来看,主要涉及到三个方法,即setup,map和cleanup方法。并且setup和cleanup是没有方法体的。

setup方法

protected void setup(Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT>.Context context) throws IOException, InterruptedException {
    }

setup方法每一个maptask方法会被调用一次,应用示例:例如做两个文件join时,可在此方法中获得文件名信息,根据文件名不同进行mapper输出的键值的传递。

cleanup方法

protected void cleanup(Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT>.Context context) throws IOException, InterruptedException {
    }

maptask结束前会被调用一次

map方法

while(context.nextKeyValue()) {  // 判断是否有下一行,有的话则将当前行的行首偏移量与文本内容传递给map方法的参数 
     this.map(context.getCurrentKey(), context.getCurrentValue(), context);
}

context.nextKeyValue()是控制开行读取的,一直读到该切片的结尾行,当没有行首便宜时即结束map方法的调用,否则每次指针的移动(指向新的行)都会调用map方法。

再来看看map方法本身

protected void map(KEYIN key, VALUEIN value, Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT>.Context context) throws IOException, InterruptedException {
    context.write(key, value);
}

由于map方法的调用频率是按行调用,所以其参数表示的意义基本和行相关。例如参数1:key,一般来说都是LongWritable类型,表示当前行的起始偏移量,所谓的起始偏移量是指从零开始的,按照每行字节多少,进行顺序递增,每一个占位表示一个偏移量。参数2:value,表示的是每一行具体的数据内容。context指的是上下文对象,上承接框架底层输入,下启shuffle阶段的输入(通常会说作为reduce阶段的输入)。

4.关于map方法的key值

通常map方法输出结果键或者值类型必须是实现了Writable接口的实现类,如果map的输出的key是默认值类型的话,对于shuffle阶段排序和分组来说,确定其次序或者分组的方法是该key类型的默认的compareTo方法。而且即便你自定义map类型,那么该自定义类型,要实现排序或者分组的话,是需要重写某些方法的。因此无论是使用默认的基本数据类型,还是自定义数据类型,key的设计至关重要,直接影响到后续shuffle阶段的排序和分组情况。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值