1.思考 MR的缺点?
- 不擅长实时计算
hadoop 的 文件是存储磁盘的 hdfs 内,传输相比内传会慢很多,相比较 Storm 和 Spark 的流处理,流处理不需要批处理的数据收集时间,也省去; 作业调度的时延。 - 不擅长流式计算
流式计算的输入数据是动态的,但是MR 的输入数据集时静态的,不能动态变化。 - 不擅长有向图的计算
多个应用存在依赖关系,后一个程序的输入是前一个的输出。MR 不能进行这样的计算,因为每个 MR 结果都会写入到磁盘,会造成大量的 IO,导致性能非常低下。
2.讲一下MR的工作原理
1) MR 运算程序一般包括两个阶段:Map 阶段和 Reduce 阶段
2)Map 阶段的并发的 MapTask ,完全并行运行,互不相干。
3)Reduce 阶段的并发 ReduceTask ,完全并行运行,互不相干,但是他们的数据依赖于上一阶段的所有MapTask 的并发实例的输出。
4)MR 的编程模型只能包含一个 Map 阶段和 Reduce 阶段,如果用户业务逻辑非常复杂,可以考虑将多个MapReduce 程序穿行运行。
涉及到一些细节问题:
(1)MapTask 的工作机制/如何工作?
(1)有一个待处理文件,在客户端 summit 之前,获得待处理数据的信息,根据参数配置,形成一个任务分配的规划,包括 job.split ,job.xml, wc.jar 。
(2)提交任务规划信息 给Yarn ,RM 启动 MrAppMaster 根据 切片的个数计算MapTask 的个数。
(3)启动MapTask,MapTask 通过InputFormat 去读文件,默认是按行读取,也可自定义InputFormat 的 RecordReader的 read()方法 去读文件,返回 k,v 键值对。
(4)对读取文件进行业务逻辑的处理,进行 context.write(k,v) ,写到 一个收集器里面OutputCollector,然后写到环形缓冲区内,环形缓冲区默认为 100m,溢写阈值是 80%,底层就是一个数组,后端不断接收数据,前端不断被溢出,当达到 80 % 后,进行溢写,溢写之前先对根据key 对数据进行分区,然后进行分区内排序,并且选择性的进行combine 操作,此时的文件是分区且有序的,溢写过程中如果有其他数据进入,那么由剩余的20%反向写入。
(5)对环形缓冲区溢出的小文件执行 merge(合并),形成分区且分区内有序的大文件(排序算法就是归并排序,相当于在调用一次 combiner 。
(6)所有的MapTask 执行完成以后,MrAppMaster 启动相应的ReduceTask,并告知 Reduce 的数据操作范围(分区信息)。
(7)Reduce 拷贝 map 端输出文件,先拷贝到内存,内存不足,再写入到磁盘,每个 ReduceTask只处理一个分区的数据。
(8)合并文件,归并排序,进入 Reduce 方法。
(9)如果设置了分组操作,进行分组(分组的目的,让两个不相同的对象,通过一个条件让其认为是一个对象,从而进入到一个Reducer 方法中。)
(10)执行用户自定义