mapreduce框架的工作机制
划分输入切片:
Job客户端负责划分
- 扫描输入目录中的所有文件
- 遍历每一个文件
- 按照128规格划分范围
- 生成arrayList
- 序列化程job.split文件
- 根据job.split知道创建几个mapTask ,明确每个mapTask会处理某个文件某一部分的内容
Map程序的启动过程
TextInputFormat类:文本文件类型的读取工具类。
- mapTask会调用TextInputFormat类得到一个LineRecordReader类
- 调用next方法从input的目录和文件中读取一行数据
- 每调用一次就会产生一堆kv其中k:行起始偏移量 v:行内容
- 调用wcMapper(自定义的类)中的map函数(k,v,context)
- 每次调用map函数之后就会在context.Write一些内容
- MapOutputCollector收集到map函数处理完的context内容
- 缓存这些写入context的数据
- 缓存类似于disruptor的那种环形的结构(一边写一边读是可以的支持的),环形缓冲区的默认大小是100M
- 如果数据量比较打的情况下,缓冲区被写到百分之八十就会开启spiller线程
- spiller线程的作用就会升降缓存区中的内容进行分区和排序
- 分区:按partitioner的getPartition()
- 排序:按key的大小进行对比
- 转移:按区的大小顺序来写入到文件磁盘当中,重新更新spiller开始处理的位置和分区。
- 溢出文件的特点:区号小的在前面,数据有进行排序,按照hashcode进行分区,同一个数据内容只会在一个文件里面出现。
- 合并磁盘上的文件,调用merge相关的工具类,合并的过程中还是会进行排序。
reduce过程
- 确定属于reduce的数据,需要找到map的机器和host
- 每个reduce都有一个编号,编号0取得就是文件中为0的区域
- reduce需要向别的机器和集群申请数据
- 每个node manager都提供web服务
- reduce服务可以通过web服务器下载需要处理的文件
- 然后只读取其中一个分区的数据,进行处理
- 将多个文件中的数据进行合并和排序,之后调用WcReducer类
- reduce(k , 迭代器,context) 每迭代一下就会创建一个value将排完序数据set到value中
- 一个一个处理数据,最后返回的结果是key相同的统计出结果
- TextOutputFormat可以获得一个writer然后将内容写到output的目录或者是hdfs
- 最后生成的part文件里面的内都是key和value的统计结果
shuffle
maptask生成的数据传输给reduce task的过程