溢写文件在哪(MapTask 工作流程)
- Mapper 的 run() 方法
- Mapper 的 cleanup() 方法
- output.close(mapperContext) 中
- collector.flush() 将环形缓冲区中的数据溢写到文件中
- sortAndSpill() 排序和溢写文件, 该方法中的 filename 就是溢写文件所在的位置, 一般文件名为 spill0.out
- mergePart() 溢写文件归并为一个文件, 通过 file.out.index 来记录每个分区的索引位置, 用以在一个文件中区分多个分区
ReduceTask 工作流程
- Reducer 的 run() 方法
- initialize() 设置默认的 OutputFormat 为 TextOutputFormat
- shuffleConsumerPlugin.init()
- new ShuffleSchedulerImpl(): 获取reduceTask的个数
- createMergeManager(context): 初始化内存和磁盘
- run()
- eventFetcher.start(): ReduceTask主动去拉取
- copyPhase.complete(): copy阶段结束
- sortPhase.complete(): sort阶段结束
- reducer.run(): 每个ReduceTask只拉取至多一个分区的数据, 进入该方法一次, 最终进入到 XXXReducer 类中的 reducer() 方法
分文件输出
分区
优点: 简单
缺点: 不能够控制输出文件名
自定义 OutputFormat
优点: 可以指定输出文件名
解决数据倾斜问题
reduceJion -> mapJion (缓存小表)