hadoop学习(二)MapReduce中的shuffle与sort

shuffle过程指的是系统将map task的输出进行排序,并将其传输至reduce task作为输入的过程。这个过程比较复杂,但也是MapReduce的精华所在。

Map阶段

首先,每个map都有一个环形的内存buffer,用来写入map的输出,这个buffer的大小默认是100mb(由mapreduce.task.io.sort.mb设置)。map运行会产生输出,并存入该buffer,当达到设定的阈值(默认0.8或80%,由mapreduce.map.sort.spill.percent设置),后台的一个线程就会开始将buffer内的数据spill(溢出,写入)到磁盘。但spill过程中map的输出还会一直写入到buffer中,直到buffer满了,才会停止,并阻塞map task,直到spill的过程结束。

但在spill线程写入磁盘之前,会首先根据将要执行的reduce task数量,进行分区(partition),并根据key在内存中排序。如果设定了combiner,会对排序的结果进行combine操作。combine操作的目的就是缩小map输出文件的大小。

因此,按照上文所述的过程,每次spill buffer达到溢出的阈值,就会生成一个spill文件,所以map task处理输入结束后,磁盘上可能会有多个spill文件。在map task结束前,会将多个spill文件合并(merge)为一个已分区并排序的大的文件作为map task的输出。同时合并的文件数最多为10个(默认值,由mapreduce.task.io.sort.factor设定)。

在合并过程中,如果spill文件的数量大于3(默认值,由mapreduce. map. combine. minspills设定),还会再执行一次combine操作。

总结一下:map阶段的shuffle过程就是

  • map产生输出,存入环形buffer
  • buffer达到溢出的阈值
  • 对buffer内数据执行partition
  • 再执行sort
  • 再执行combine(可选)
  • 生成一个spill文件,存入磁盘
  • 多次达到spill阈值,生成多个spill文件
  • 对多个spill文件执行合并(merge)操作,生成一个大的已分区的已排序的输出文件写入磁盘
  • 如果spill文件数量大于3,在合并过程的最后执行combine操作。
reduce阶段
copy阶段

首先要注意的是,map输出的文件一定是存在执行map task的节点的本地磁盘上。而reduce task要做的是从集群内所有执行map task的节点处获取它对应的partition的数据。由于map的结束时间不会相同,为了增加效率,reduce task会生成多个线程(默认为5个,由mapreduce.shuffle.parallelcopies设定),每当map task结束就会并行的复制所需的partition数据。

当map task执行成功,会通过心跳机制通知app master(见MapReduce中Job的执行过程),而reduce task会周期的向app master获取map task输出的信息,直到所有map都结束。

这样,多个map的输出就在不同的时间汇聚到reduce所在的节点。而reduce会根据map输出文件的大小将其存储在不同位置,小的话就存在内存,大的话就直接存在硬盘。这个大小的标准就是reduce的input buffer(由mapreduce. reduce. shuffle. input. buffer. percent设定)。

当buffer达到一个阈值(mapreduce. reduce. shuffle. merge. percent)或者buffer内的输出文件数量达到一定数量(mapreduce. reduce. merge. inmem. threshold),buffer中的数据就会先合并、再写入到磁盘。如果指定了combiner,在写入之前会执行combine操作,减少磁盘的写入。

当磁盘写入的数据不断累积,一个后台的线程会将他们合并成更大的已排序的文件。这将会节省后期合并的时间。

sort阶段

当所有的数据复制完毕,reduce进入sort阶段。更确切的说,其实应该叫merger阶段,因为sort的过程在map task已经做过了。

如果需要合并的文件较多,sort的合并会进行若干轮。每轮合并的最多文件数由mapreduce.task.io.sort.factor设定,和map一样。最后的结果就是生成一个单独的已排序的大文件。当然,reduce内部会对这个过程做一些优化,节省执行的时间。

reduce阶段

最后的reduce阶段就很简单了,只需要按行读取sort的输出文件,执行reduce方法即可。reduce的输出会直接存储到目标文件系统,通常是HDFS。

总结一下,Reduce阶段的整个过程:

  • 生成多个线程,从各个map节点获取数据
  • 如果数据小,就存入内存buffer,大的话,就直接存磁盘
  • 当buffer内数据大小或存储的文件数达到阈值,对buffer内的数据执行merge,并存入磁盘。
  • 磁盘内的数据不断增多,会有一个后台线程执行merge
  • 所有map输出文件复制完毕,copy阶段完毕
  • sort阶段将磁盘上所有复制的文件merge成一个大的已排序的文件
  • reduce阶段在这个文件上执行reduce方法,并将结果存入hdfs

最后的想法是,shuffle所解决的问题就是在集群内将map产生的输出文件,分区,排序,合并,并提供给reduce使用。但因为集群内的节点数量较多,为了提高传输的效率,在这个过程中做了很多优化,提高了整体的执行效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值