10. 请说下 MR 中 Map Task 的工作机制
简单概述:
inputFile 通过 split 被切割为多个 split 文件,通过 Record 按行读取内容给map(自己写的处理逻辑的方法)
,数据被 map 处理完之后交给 OutputCollect 收集器,对其结果 key 进行分区(默认使用的 hashPartitioner),然后写入 buffer,每个 map task 都有一个内存缓冲区(环形缓冲区),存放着 map 的输出结果,当缓冲区快满的时候需要将缓冲区的数据以一个临时文件的方式溢写到磁盘,当整个 map task 结束后再对磁盘中这个 maptask 产生的所有临时文件做合并,生成最终的正式输出文件,然后等待 reduce task 的拉取
详细步骤:
1)读取数据组件 InputFormat (默认 TextInputFormat) 会通过 getSplits 方法对输入目录中的文件进行逻辑切片规划得到 block, 有多少个 block 就对应启动多少个 MapTask.
2)将输入文件切分为 block 之后, 由 RecordReader 对象 (默认是LineRecordReader) 进行读取, 以 \n 作为分隔符, 读取一行数据, 返回 <key, value>. Key 表示每行首字符偏移值, Value 表示这一行文本内容
3)读取 block 返回 <key,value>, 进入用户自己继承的 Mapper 类中,执行用户重写的 map 函数, RecordReader 读取一行这里调用一次
4)Mapper 逻辑结束之后, 将 Mapper 的每条结果通过 context.write 进行collect 数据收集. 在 collect 中, 会先对其进行分区处理,默认使用HashPartitioner
5)接下来, 会将数据写入内存, 内存中这片区域叫做环形缓冲区(默认 100M), 缓冲区的作用是 批量收集 Mapper 结果, 减少磁盘 IO 的影响. 我们的Key/Value 对以及 Partition 的结果都会被写入缓冲区. 当然, 写入之前,Key 与 Value 值都会被序列化成字节数组
6)当环形缓冲区的数据达到溢写比列(默认 0.8),也就是 80M 时,溢写线程启动,
需要对这 80MB 空间内的 Key 做排序 (Sort). 排序是 MapReduce 模型默认的行为, 这里的排序也是对序列化的字节做的排序
7)合并溢写文件, 每次溢写会在磁盘上生成一个临时文件 (写之前判断是否有Combiner), 如果 Mapper 的输出结果真的很大, 有多次这样的溢写发生, 磁盘上相应的就会有多个临时文件存在. 当整个数据处理结束之后开始对磁盘中的临时文件进行 Merge 合并, 因为最终的文件只有一个, 写入磁盘, 并且为这个文件提供了一个索引文件, 以记录每个 reduce 对应数据的偏移量
11. 请说下 MR 中 Reduce Task 的工作机制
简单概述:
Reduce 大致分为 copy、sort、reduce 三个阶段,重点在前两个阶段。copy 阶段包含一个 eventFetcher 来获取已完成的 map 列表,由 Fetcher 线程去 copy 数据,在此过程中会启动两个 merge 线程,分别为 inMemoryMerger 和onDiskMerger,分别将内存中的数据 merge 到磁盘和将磁盘中的数据进行merge。待数据 copy 完成之后,copy 阶段就完成了,开始进行 sort 阶段,sort 阶段主要是执行 finalMerge 操作,纯粹的 sort 阶段,完成之后就是 reduce 阶段,调用用户定义的 reduce 函数进行处理
详细步骤:
1)Copy 阶段:简单地拉取数据。Reduce 进程启动一些数据 copy 线程(Fetcher), 通过 HTTP 方式请求 maptask 获取属于自己的文件(map task 的分区会标识每个map task 属于哪个 reduce task ,默认 reduce task 的标识从 0 开始)。
2)Merge 阶段:这里的 merge 如 map 端的 merge 动作,只是数组中存放的是不同 map 端 copy 来的数值。Copy 过来的数据会先放入内存缓冲区中,这里的缓冲区大小要比 map 端的更为灵活。merge 有三种形式:内存到内存;内存到磁盘; 磁盘到磁盘。默认情况下第一种形式不启用。当内存中的数据量到达一定阈值, 就启动内存到磁盘的 merge。与 map 端类似,这也是溢写的过程,这个过程中如果你设置有 Combiner,也是会启用的,然后在磁盘中生成了众多的溢写文件。第二种 merge 方式一直在运行,直到没有 map 端的数据时才结束,然后启动第三种磁盘到磁盘的 merge 方式生成最终的文件。
3)合并排序:把分散的数据合并成一个大的数据后,还会再对合并后的数据排序。
4)对排序后的键值对调用 reduce 方法,键相等的键值对调用一次 reduce 方法, 每次调用会产生零个或者多个键值对,最后把这些输出的键值对写入到 HDFS 文件中。
另一版本:
9.内存角度介绍Map的输出到Reduce的输入的过程。
Map的输出到内存
Map将数据传入环形缓冲区,默认100MB 可修改,环形缓冲区中的数据到达一定的阈值时,默认0.8 可修改,进行溢写生成好多临时文件,多个临时文件到达10个(可以调整)merge合并成一个大文件。
Reduce数据读取
reduce会主动去发起拷贝线程到maptask获取属于自己的数据,数据会进入ReduceTask中的环形缓冲区,当缓冲区中的数据量到达
一定阈值进行溢写,多个临时文件merge合并成一个大文件,最后输入到Reduce。