1.TextInputFormat.addInputPath("xx.log") 对文件进行切分,切出来一个个的FileSplit对象{文件内容从哪里开始读取,读取多少行 ,文件在哪个服务器} 切片的切分依据为128M ,当最后一个数据块大小为140.8M时也不会切分(数据块大小/128<1.1时)。
2.切片之后启动 MapTask,MapTask数量和切片数量相同,MapTask会循环调用其中的map方法,次数为数据行数,会输出key- value 数据
3.在MapTask输出之后,kv会进入到计算分区的方法中Partitioner.getPartition(),针对每一行数据会输出一个分区号 默认: key.hashCode() % ReduceTask个数
4.环形缓冲区: 所有MapTask输出的数据(计算过分区的)都会进入环形缓冲区 它是一个默认100M大小的内存空间,当写入80%的时候,会触发spill溢写操作,同时也在继续的进行数据的接入,保证数据读写的并行效率,不会等待
5.溢写Spill: 溢写开启之后,环形缓冲区开始对byte数组中的待溢写数据进行排序,排过之后直接输出为一个溢写临时文件,并且此文件有分区标识。不同分区的数据会放入到不同的溢写临时文件中。(如果文件比较大,则一次溢写只能溢写出来一部分数据),如果还有数据从MapTask端输出,则会根据数据的情况(是否再次达到溢写条件或MapTask数据已输出完)而再次输出,自然会出现多个溢写临时文件,每一个文件中的数据是有序的,而多个溢写临时文件之间无序。 此时多个溢写临时文件不可直接使用,需要进行一次归并排序
6.从MapTask服务器到ReduceTask服务器的数据传输(不同机器) 下载:临时文件通过网络发送 合并:归并排序 分组聚合:以key作为分组依据,value作为一个可迭代对象中的元素 进行存放
7.根据key的数据循环调用 Reducer.reduce()方法,TextOutputFormat 负责将数据输出到指定的文件夹中