Shuffle详解

来源:互联网 发布:jsp从sql server中取值 编辑:程序博客网 时间:2024/06/11 19:00

Shuffle过程是MapReduce的核心。Shuffle的意思是洗牌或者打乱,会使用Java的同学应该见过Java API里面的Collections.shuffle(list)方法,它会随机地打乱参数list里面的元素顺序。
如果读者不知道MapReduce里面的Shuffle是什么,请看下图
这里写图片描述
Shuffle差不多就是从MapTask输出到ReduceTask输入的这一过程。
在真实的Hadoop集群环境中,可能大部分的MapTask和ReduceTask不在同一个节点上。所以很多时候Reduce执行之前需要跨界点去获取其他节点上MapTask的结果。如果集群正在运行的Job有很多,这样正常执行集群内部的网络资源会消耗的非常严重。
我们能做的就是最大化的减少不必要的消耗。
在节点内,相比于内存,磁盘的IO对job完成的时间的影响也是非常明显的。
所以在跨节点获取数据时,尽可能减少对带宽的不必要的消耗。以及磁盘IO对Task执行的影响。

举个栗子:

Map端

比如现在有一个job,经过Mapper的运行之后,输出的都是Key/Value的键值对。到底现在Mapper输出的结果交由那个Reducer执行,默认是这样计算的,首先对Key进行Hash运算之后,在对RecudeTask的数量取模。来决定当前Map输出的数据交由哪个reduce处理。
接下来需要将数据写入内存缓冲区中。缓冲区的作用是批量采集Map的结果,减少磁盘IO对job运行时间的影响。
但是内存缓冲区是有大小限制的,默认是100MB。当MapTask的输出结果有很多时,内存可能会不足,所以需要在一定的条件下将缓冲区中的数据临时写入到磁盘上,然后重新利用这个缓冲区。这个从内存向磁盘写数据的过程叫Spill,也就是溢写。和flush很像。
每次溢写都会在磁盘上生成一个溢写文件,如果Map的输出结果很大,就会有多个这样的溢写文件。当MapTask真正完成时,内存缓冲区中的数据将全部溢写到磁盘中形成一个溢写文件。最终磁盘中会至少有一个溢写文件。
如果磁盘中的溢写文件有多个,则需要将这些溢写文件归并到一起,这个过程叫做Merge。到这里为止。Map端的所有工作才算结束

Reduce端

每个ReduceTask不断的从JobTracker那里获取MapTask是否完成的信息。如果ReduceTask知道某个TaskTRacker上的MapTask执行完成,那么Shuffle的后半段过程开始启动。对从不同地方获得的数据不断的进行Merge,最终形成一个文件作为ReduceTask的输入文件。

copy阶段

就是简单的复制数据。Reduce进程启动一些数据copy线程(类似Git的Fetch过程),通过HTTP方式请求MapTask所在的TaskTracker获取MapTask的输出文件。因为MapTask早就结束了,所以这些文件都是TaskTracker管理的。

Merge阶段

和Map端的Merge相同,只不过内存中存放的是不同的Map端复制过来的数据。复制过来的数据会先放入内存缓冲区中,当内存中的数据量达到一定的阈值时,会启动内存到磁盘的Merge。与Map端类似。也就是溢写的过程,会在磁盘中生成多个溢写文件,然后将这些溢写文件进行合并。

Reducer的输入文件

在不断的进行Merge后,会生成一个唯一的文件。这个文件可能存放在磁盘上,也可能存放在内存中,默认存放在磁盘上。当Reducer的输入文件确定时,整个Shuffle过程才最终结束。

原创粉丝点击