混洗和排序


在mapreduce过程中,map输出的结果默认是按照key进行排序的,这个排序的过程加上与将map的输出结果传送到reducer作为输入的过程统称为混洗。理解混洗的过程对于理解整个hadoop很有帮助,书中也提到混洗就是hadoop发挥它威力的地方。

1. map side:
map函数执行后会不断的产生结果,这些结果不是简单的写入磁盘的。每个map任务都有一个循环队列,map输出结果首先会存放在队列中,当队列 中存放的内容超过一个门限值的时候(通过io.sort.spill.percent设置,默认为0.8, 80%),一个后台线程将队列中的内容写到磁盘中,此时map结果的写入到队列的过程并没有停止,当队列慢了以后,map现成会被阻塞直到队列中所有的数 据都写入到磁盘。

在队列的内容被写入磁盘之前,线程首先将数据进行分组,分组的自然是按照最终会传送到哪个reducer进行。对于每个组,线程会对组中的数据按key排序,如果声明了combiner函数,在此时调用,然后将结果写入到一个文件中。

每次队列达到门限值的时候,都会产生一个这样的文件,文件达到一定数目或map任务要结束的时候,这些文件会merge成一个已经分组的有序的文 件,如果声明了combiner函数,并且至少有三个这样的中间文件进行merge,就会调用此combiner。最终将这个已分区的有序的文件写入磁盘 中。

2. reduce side:
在reduce side,混洗分为三个阶段:拷贝阶段、排序(归并)阶段、reduce阶段
reduce task默认有5个线程来拷贝已完成的map任务的相应分区。当map任务完成并将最终的那个文件写入到磁盘后,拷贝就会开始,reduce task不会等所有的map task都完成,而是有map task完成后,拷贝阶段就开始。reduce task将map task的结果通过http协议传送到队列中,当超过队列规定的容量或者已经获得从map task结果的数目达到门限值,就开始将这些数据写入磁盘中。

当所有的map task的结果都拷贝结束后,reduce task进入排序(归并)阶段,这个阶段会按照设置的归并因子来进行归并,比如有50个map结果,归并因子是10,则会归并5次,每次将10个文件归并为一个文件。

进行一次归并后,便进入到reduce阶段,将上阶段生成的多个文件作为reduce的输入,进行reduce操作,获得的结果进行最后一个归并,得到最终结果并将结果写入到HDFS中。

至此整个mapreduce的执行过程结束了,整个过程书上的图描述的很清楚:
混洗和排序_第1张图片

我们可以优化混洗的过程来优化整个job的性能。在map side,我们应该尽量避免map的结果不断的写入到磁盘,可以提高io.sort.mb来增加循环队列的容量;在reduce side,应尽量保证中间数据都在内存中,我们可以设置接受map结果的门限值为0和设置缓冲区溢出百分比为100%来获得最佳性能。

你可能感兴趣的:(mapreduce,hadoop,中间件)