Hadoop的权威指南(汤姆·怀特),第178页,章节洗牌和排序:地图一侧。就在图6-4之后
在写入磁盘之前,线程首先将数据划分为与reducers相对应的分区,这些数据最终将被发送到这些分区。对于每个分区,后台线程按键执行内存中的排序,如果有组合器函数,则在排序的输出上运行WIthin。
问题:
这是否意味着映射将每个键输出写入不同的文件,然后将它们组合在一起。因此,如果有两个不同的密钥输出要发送到reducer,则每个不同的密钥将分别发送到reducer,而不是发送单个文件。
如果我上面的推理是不正确的,那么实际发生了什么呢?
发布于 2013-06-08 23:41:56
只有当两个关键输出到不同的reducers时。如果分区认为它们应该转到相同的reducer,那么它们将在相同的文件中。
--更新以包含更多细节-主要来自本书:
分区程序只是对存储桶中的密钥进行排序。从0到n表示作业中的减速机数量。reduce任务具有少量的复制器线程,因此它可以并行获取map输出。因此,对于给定的作业,jobtracker知道map输出和主机之间的映射。reducer中的线程周期性地向主程序请求映射输出主机,直到它检索到所有主机为止。
如果map输出足够小,则将其复制到reduce任务JVM的内存中(缓冲区的大小由mapred.job.shuffle.input.buffer.percent控制,它指定用于此目的的堆的比例);否则,将它们复制到磁盘。当内存中的缓冲区达到阈值大小(由mapred.job.shuffle.merge.percent控制)或达到贴图输出的阈值数量(mapred.inmem.merge.threshold)时,它将被合并并溢出到磁盘。如果指定了组合器,它将在合并过程中运行,以减少写入磁盘的数据量。
随着副本在磁盘上的累积,后台线程会将它们合并到更大的排序文件中。这节省了一些以后合并的时间。请注意,任何(由map任务压缩的) map输出都必须在内存中进行解压缩,以便对它们执行合并。
复制完所有映射输出后,reduce任务将进入排序阶段(应该将其称为合并阶段,因为排序是在映射端执行的),该阶段将合并映射输出,并保持其排序顺序。这是在循环中完成的。例如,如果有50个map输出,合并因子为10 (默认值,由io.sort.factor属性控制,就像在map的合并中一样),则将有五轮。每一轮都会将10个文件合并为一个文件,因此在结束时将有5个中间文件。
合并不会进行最后一轮将这五个文件合并到单个排序文件中,而是通过在最后一个阶段: reduce阶段直接提供reduce函数来节省磁盘行程。最终的合并可以来自内存中和磁盘上的段的混合。
发布于 2013-06-09 16:27:24
如果我们配置了多个reducer,那么在分区过程中,如果我们得到不同reducer的key,它们将被存储在与reducer对应的单独文件中,并且在map任务结束时,完整的文件将被发送到reducer,而不是单个key。
发布于 2013-06-10 14:20:21
比方说,你有3个减速器在运行。然后,可以使用分割器来确定哪个关键点属于三个减速器中的哪一个。您可能可以在分区程序中执行X%3,以确定哪个键属于哪个缩减程序。Hadoop默认使用HashPartitioner.
https://stackoverflow.com/questions/16996223
复制相似问题