MapReduce整个流程

一、map端

1、由InputFormat的默认实现类TextInputFormat调用createRecoderReader()方法,返回一个RecoderReader对象调用read()方法来读取,返回kv键值对。
2、将返回的kv键值对输入到map()函数,作为传入参数,经过用户自定义的逻辑后,由context.write()方法输出。
3、此时,输出会被outputCollector.collect()方法收集,并且写入到环形缓冲区。
4、环形缓冲区底层是一个字节数组,在输出数据不断往后写入到同时,前面的数据会不断向外溢写,环形缓冲区的默认大小为100M,可以通过mapreduce.task.io.sort.mb设置,另外,环形缓冲区的溢写阈值为0.8,也可以通过mapreduce.map.sort.spill.percent进行设置。同时,如果输出数据写入时,环形缓冲区的内存不够了,写入会被阻塞,直到溢写完成。
5、溢写文件的过程中会对数据进行分区(默认是hash分区(key.hashCode()&Integer.Max_VALUE)%numReduceTasks),然后对key进行排序,如果有用户自定义的combiner函数则会执行。就这样会溢写出多个小文件。
6、多个溢写文件合并成分区且区内有序的大文件,如果溢写文件大于3则会再次进行combiner()函数,让结果更加紧凑,减少磁盘IO和之后的网络IO。
7、也可以对map的输出进行数据的压缩,节约磁盘,网络传输更快。

二、reduce端

1、reduce会通过http从各个maptask任务所在的节点拉取该分区的数据。
2、通过groupingcomparetor()函数,将所有key相同的键值对都放在一组,形成(k,iterator),作为reduce()方法的输入参数,经过用户自定义的逻辑后,通过context.write()方法输出。
3、会通过OutputFormat调用RecordWriter对象的write()方法将输出写入数据库。

三、reducer如何知道从哪个节点获得map输出?

map任务完成后,会通过心跳机制向application master汇报,因此application master 知道对应的map输出和节点的位置关系。同时,reduece会使用一个线程定时访问application master获取map输出和节点的位置关系,直到获得所有的位置。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值