今天开始看hadoop的源码,代码经验实在是很少,所以就从最熟悉的、最简单的开始看起。先种树,再见林吧。
先从demo看起。最常见的demo是wordcount,就是统计预料中词频。
mapreduce程序元素:
这是一个最基本的mapreduce程序,程序中必须要写的元素有:
mapper
reducer
mapreduce执行流程:
1.设置JobConf,一系列的conf.set方法,可配置的参数有:
mapper、combiner、reducer、outputKeyClass、outputValueClass、mapper
count、reducer count、inputformat、outputformat
2.JobClient通过JobConf执行mapreduc程序
mapper
org.apache.hadoop.mapred.Mapper
Mapper是一个接口,只有一个map方法,因此Mapper相当于一个函数对象,通过它来处理每一对,最终将其写入到OutputCollector中,Mapper的任务就结束了。
public interface Mapper extends JobConfigurable, Closeable {
void map(K1 key, V1 value,
OutputCollector output,
Reporter reporter)
};
Mapper还继承了两个接口:JobConfigurable和Closeable,JobConfigurable提供一个void
configure(JobConf
job);函数来访问JobConf。Mapper可以通过它来访问JobConf中的配置;Closeable已经废弃,在19.2版本中是一个空接口。实际使用中这两个接口实际上不常用,因此提供了MapReduceBase类——该类提供了对应的两个空的实现。
Mapper接口有四个模板参数:分别为输入、输出的key、value类型。
map函数接受四个参数,分别为输入key、value值,输出流(OutputCollector,包含两个模板参数,为输出的key、value),reporter。
reporter:作用为统计、汇报状态。是一个接口,没有见到具体的实现,先记录下来,后面再看。
Mapper与上下游交流的流程为(该流程由框架支持,下面所有粗体的位置用户可配):
Mapper从InputSplit中读取输入流,InputSplit由InputFormat生成。
Mapper的输出将被框架有序化排列,排序方式可以通过JobConf.setOutputKeyComparatorClass(Class)指定;排序后可以通过JobConf.setCombinerClass(Class)对输出进行规约,以减少输出量;最后,指定Partitioner来决定某一组具体被分到哪一个reducer中。输出被存储在SequenceFile中,可以指定CompressionCode来对输出文件进行压缩,以降低shuffle数据量。
reducer
org.apache.hadoop.mapred.Reducer
基本功能与Mapper相似,定义为:
public interface Reducer extends JobConfigurable, Closeable
{
void
reduce(K2 key, Iterator
values,
OutputCollector output, Reporter
reporter)
throws IOException;
}
与mapper的不同点在于输入value不是一个值而是一个迭代器(Iterator,hasNext、next两个函数)。
Reducer与上下游交互的流程为:
shuffle:使用http从每个mapper端要到本reducer需要处理的数据
sort:多路归并、外排序,这里有个secondary
sort,没太看明白
reduce:处理输入数据
to be continued:
- reporter
- 输入输出类型:Text、IntWritable
- OutputCollector
-
secondary sort
-
reduce的shuffle、sort的实现