Map Reduce
Mapper接口
extends Mapper<LongWritable, Text, Text, IntWritable>
输入key类型,输入value类型,输出key类型,输出value类型
void map(LongWritable, Text, Context)
输入key类型,输入value类型
context.write(Text, IntWritable)
输出key类型,输出value类型
Reducer接口
extends Reducer<Text, IntWritable, Text, IntWritable>
输入key类型,输入value类型,输出key类型,输出value类型
void reduce(Text, Iterable<IntWritable>, Context)
输入key类型,输入value类型
context.write(Text, IntWritable)
输出key类型,输出value类型
MapReduce机制
角色:client, JobTracker, TaskTracker, HDFS
Client: 提交job到JobTracker
JobTracker: 分发任务给TaskTracker, 输入分片 Input Split
TaskTracker: 执行小任务,每个分片一个map任务
HDFS:存储数据
过程:
- 输入分片(Input Split):分片在在HDFS里
- map:输入分片split,输出到内存缓冲区
- shuffle: 排序,key相同的数据放在一起,分区 partitioner
- reduce: 一个分区partition对应一个reduce
shuffe阶段
- partition: 根据key把k-v放入某个partition。在内存缓冲区优化,决定数据交给哪个reducer处理,负载均衡
- spill: 每个partition里的k-v进行排序,并且执行combine。sort & combine,优化,通常跟reducer是一样的,写磁盘
- merge: 每个partition里的k-v写成group:k-list(?) 磁盘可能有多个溢写文件,需要merge成一个?merge成group: key, list?
- fetch: 从不同的map拉取中间结果
- merge: 合并来自不同map的输出文件
分片 split
- 根据map task的数量来确定分片的数目,确定分片的大小
分区 partition
- 为了解决map的结果数据太大?交给多个reduce去处理?
- 同一个key的所有数据都写入同一个分区?不能分散到多个分区?
- 分区的数量默认由reducer确定,一个分区里包括多个key
- map会把输出数据写到多个分区文件?
- reduce去map拉取分区文件,然后处理?
归并排序
- 先把大数组分解成小数组
- 小数组两两排序
谢谢阅读!