MapReduce的运⾏流程

本文详细介绍了MapReduce的运行流程,包括MRAppMaster的职责、MapTask如何处理数据以及ReduceTask的工作过程。此外还探讨了MapTask和ReduceTask的并发度设置原则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、MapReduce运⾏流程简述

二、运⾏流程之MapTask

三、运⾏流程之ReduceTask


一、MapReduce运⾏流程简述

⼀个完整的 MapReduce 程序在分布式运⾏时有三类实例进程:
         1) MRAppMaster:负责整个程序的过程调度及状态协调
         2) MapTask:负责 map 阶段的整个数据处理流程
         3) ReduceTask:负责 reduce 阶段的整个数据处理流程
当⼀个作业提交后(mr程序启动),⼤概流程如下:
1) ⼀个 mr 程序启动的时候,会先启动⼀个进程 Application Master, 它的主类是 MRAppMaster
2) appmaster 启动之后会根据本次 job 的描述信息,计算出 inputSplit 的数据,也就是MapTask 的数量
3) appmaster 然后向 resourcemanager 来申请对应数量的 container 来执⾏MapTask进程。
4) MapTask 进程启动之后,根据对应的 inputSplit 来进⾏数据处理,处理流程如下
         - 利⽤客户指定的 inputformat 来获取 recordReader 读取数据,形成 kv 键值对。
         - kv 传递给客户定义的 mapper 类的 map ⽅法,做逻辑运算,并将 map ⽅法的输出kv收集到缓存。
         - 将缓存中的 kv 数据按照 k 分区排序后不断的溢出到磁盘⽂件
5) appmaster 监控 maptask 进程完成之后,会根据⽤户指定的参数来启动相应的reduceTask进程,并告知 reduceTask 需要处理的数据范围
6) reducetask 启动之后,根据 appmaster 告知的待处理的未知数据,从若⼲的已经存到磁盘的数据中拿到数据,并在本地进⾏⼀个归并排序,然后,再按照相同的key 的kv为⼀组,调⽤客户⾃定义的 reduce ⽅法,并收集输出结果 kv ,然后按照⽤户指定的outputFormat将结果存储到外部设备。
 参考下图:

 

二、运⾏流程之MapTask

1. maptask 调⽤ FileInputFormat getRecordReader 读取分⽚数据
2. 每⾏数据读取⼀次,返回⼀个 (K,V) 对, K offset,V 是⼀⾏数据
3. k-v 对交给 MapTask 处理
4. 每对 k-v 调⽤⼀次 map(K,V context) ⽅法,然后 context.write(k,v)
5. 写出的数据交给收集器 OutputCollector.collector() 处理
6. 将数据写⼊环形缓冲区,并记录写⼊的起始偏移量,终⽌偏移量,环形缓冲区默认 ⼤⼩100M
7. 默认写到 80% 的时候要溢写到磁盘,溢写磁盘的过程中数据继续写⼊剩余 20%
8. 溢写磁盘之前要先进⾏分区然后分区内进⾏排序
9. 默认的分区规则是 hashpatitioner ,即 key hash%reduceNum
10. 默认的排序规则是 key 的字典顺序,使⽤的是快速排序
11. 溢写会形成多个⽂件,在 maptask 读取完⼀个分⽚数据后,先将环形缓冲区数据 刷写到磁盘
12. 将数据多个溢写⽂件进⾏合并,分区内排序(外部排序 === 》归并排序)
        MapTask的并⾏度决定map阶段的任务处理并发度,进⽽影响到整个job的处理速度.那么,MapTask并⾏实例是否越多越好呢?其并⾏度⼜是如何决定呢? 
1) 如果硬件配置为 2*12core + 64G ,恰当的 map 并⾏度是⼤约每个节点 20-100 个map,最好每个 map 的执⾏时间⾄少⼀分钟。
2) 如果 job 的每个 map 或者 reduce task 的运⾏时间都只有 30-40 秒钟,那么就减少该job map 或者 reduce 数,每⼀个 task(map|reduce) setup 和加⼊到调度器中进⾏调度,这个中间的过程可能都要花费⼏秒钟,所以如果每个task 都⾮常快就跑完了, 就会在task 的开始和结束的时候浪费太多的时间。
3) 配置 task JVM 重⽤可以改善该问题:
(mapred.job.reuse.jvm.num.tasks ,默认是 1 ,表示⼀个 JVM 上最多可以顺序执⾏的task 数⽬(属于同⼀个 Job )是 1 。也就是说⼀个 task 启⼀个 JVM
4) 如果 input 的⽂件⾮常的⼤,⽐如 1TB ,可以考虑将 hdfs 上的每个 block size 设⼤,⽐如设成256MB 或者 512MB

三、运⾏流程之ReduceTask

1. 数据按照分区规则发送到 reducetask
2. reducetask 将来⾃多个 maptask 的数据进⾏合并,排序(外部排序 === 》归并排序)
3. 按照 key 相同分组()
4. ⼀组数据调⽤⼀次 reduce(k,iterable<v>values,context)
5. 处理后的数据交由 reducetask
6. reducetask 调⽤ FileOutputFormat 组件
7. FileOutputFormat 组件中的 write ⽅法将数据写出
        Reduce Task的并⾏度同样影响整个 job 的执⾏并发度和执⾏效率,但与 Map Task 的并发数由切⽚数决定不同,Reduc Task 数量的决定是可以直接⼿动设置:默认值是 1,⼿动设置为 4
设置⽅法 :job.setNumReduceTasks(4);
如果数据分布不均匀,就有可能在 reduce 阶段产⽣数据倾斜
注意: Reduce Task 数量并不是任意设置,还要考虑业务逻辑需求,有些情况下,需 要计算全局汇总结果,就只能有1 Reduce Task ,尽量不要运⾏太多的Reduce Task 。对⼤多数 job 来说,最好 reduce 的个数最多和集 群中的reduce 持平,或者⽐集群的 reduce slots ⼩。这个对于⼩集群⽽⾔,尤其重 要。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值