mapreduce的执行流程
首先框架会把
文件切割成
一个一个的split,然后
一个split就会对应
一个map任务。
默认情况下
一个split的大小和block size的大小是一样的,都是128MB。然后框架会为每
一个split创建
一个行阅读器,
一个行阅读器会把每一行的数据给读出来,组装成<k1,v1>。这里有
一个小细节,如果一行数据在两个split里面,那么会不会出错呢?答案是不会,因为每
一个split框架会多读一行数据,也就是多读取下
一个split的数据,而下
一个split来读取的时候就会从第二行开始读取数据,那么这样的话两个split就不会出现这种情况。
之后对于map任务,他会把<k1,v1>执行对应逻辑然后
输出为<k2,v2>,然后框架会对
输出的<k2,v2>进行分区处理。再之后相同分区的数据会进行排序和分组。完了之后看是否有
自定义的Combiner操作,如果有的话那么就会提前来计算以下Reduce端的计算逻辑。Map结束后就是Shuffle操作,Shuffle操作的本质就是在网络中拷贝数据。也就是把相同分区的数据拷贝到同
一个Reduce端。然后在Reduce端同
一个分区的数据会进行排序合并操作,之后再执行reduce的逻辑
输出<k3,v3>,然后把<k3,v3>写到磁盘上,自此reuce端也就结束了。
此外再来叙述以下mapreduce的其他细节。mapreduce的主要时间损耗是在磁盘的IO上,在map的过程,框架会把map任务的
输出<k2,v2>首先
输出到内存中,当内存中的数据达到百分之80的之后,他会把数据溢写到
文件中。之后在把内存的数据写到
文件上,这就经历了
一个磁盘IO,然后再把数据通过shuffle过程拷贝对应的分区,拷贝到分区之后也是先去写到reduce端的
文件中。然后reduce程序在从
文件中读取数据来进行reduce的逻辑。
因此数据在磁盘IO的占比消耗是非常大的,那么这个逻辑既然避免不了,如何优化以下。这就是Hadoop为什么要使用自己的数据类型,而不用java
自带的数据类型。这是因为Hadoop自己的数据类型实现了Hadoop自身的序列化机制,Hadoop自身的序列化机制是非常轻量级的,这可以大幅度减弱IO读写
文件的消耗。
以上就是本人关于mapreduce的一些个人理解,如果有不足或者不对的地方欢迎指正。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。