递交job流程
一个MR任务会递交一个 job,MR任务包括 MapTask 和 ReduceTask 任务。
会在 jobid 命名的目录下递交3个文件:切片信息文件,MR的配置信息,待执行程序的jar包
默认的InputFormat和RecordReader
hadoop 默认的 InputFormat 是 TextInputFormat,TextInputFormat方法默认返回一个 LineRecordReader。
环形缓冲区
每个 map task 会启动一个环形缓冲区。
- 默认的环形缓冲区大小为100M,对一个 map task,默认的切片大小为128M。
- 当环形缓冲区达到80%时,即 80M时,会触发溢写,将在环形缓冲区中的80M数据分区内排序,然后溢写到磁盘文件中。(快排排索引,即环形缓冲区中 存储的元数据 的索引)
- 切片大小大于80M,所以一个map task可能会生成多个 溢写文件。
- 将多个 溢写文件 合并为一个大文件。此时会进行一次归并排序,继续保证文件分区内有序。
- 经过上述步骤,一个 map task 形成一个大文件。
多个map task 会形成多个大文件,这些大文件可以视情况使用 Combiner 进行一次合并(类似于 reduce task 做的归并排序)。
几次排序及合并文件总结
下面的文件均为分区内有序
每个 MapTask 由一个进程执行,每个 MapTask 任务会有一个对应的环形缓冲区,环形缓冲区可能会满多次,发多次溢写,因此会形成多个溢写文件,这些溢写文件会进行归并排序合并成一个大文件
- 多个MapTask生成的大文件进行一次归并排序形成一个大文件(可选流程)
- Reduce阶段会主动拉取每个 MapTask 形成的大文件某个分区的数据,进行一次归并排序。(会先尝试放在内存里,如果放的下,直接进行归并排序,从内存里直接传给 ReduceTask)。
一般一个分区的文件都比较大,内存放不下,会先一个一个拉到 Reduce 的磁盘中,然后再将拉到 Reducer 的文件进行归并排序 得到一个整体有序(单个分区的)的大文件,对这个大文件按 key 分组,将分好组的数 据传给Reducer。
分区总结
分区的个数核心由 ReduceTask 的个数决定。
(1)ReduceTask 的个数 > 分区数,则会产生几个空的输出文件,如 part-r-000xx
(2)ReduceTask 的个数为1,不管分区数为多少,最终只会输出一个文件,part-r-00000
(3)ReduceTask 的个数 < 分区数,一部分分区数据无处安放,会产生 Exception
Hadoop集群资源分配问题
集群有30台机器,跑mr任务的时候发现5个map任务全都分配到了同一台机器上,这个可能是由于什么原因导致的吗?
解决方案:yarn.scheduler.fair.assignmultiple这个参数 默认是开的,需要关掉。
该参数控制 是否允许NodeManager一次分配多个容器,开着,则可能在一台机器上同时开启多个容器,同时跑多个map任务。
