Hadoop权威指南(汤姆怀特)第178页 部分洗牌和排序:地图方面。 就在图6-4之后
在写入磁盘之前,线程首先将数据划分为与最终将被发送到的reducer相对应的分区。在每个分区中,后台线程按键执行内存中排序,如果有组合器函数,则在排序的输出上运行。
问题:
这是否意味着地图会将每个键输出写入不同的文件,然后再将它们合并。 因此,如果要将2个不同的键输出发送到reducer,则每个不同的键将单独发送到reducer而不是发送单个文件。
如果我的上述推理不正确,那实际发生了什么。
答案 0 :(得分:4)
仅当两个关键输出转向不同的减速器时。如果分区认为它们应该转到相同的reducer,它们将在同一个文件中。
- 更新以包含更多详细信息 - 主要来自本书:
分区程序只是将密钥排序到存储桶中。 0到n表示作业中的减速器数量。 reduce任务具有少量的复制器线程,因此它可以并行获取映射输出。因此,对于给定的作业,jobtracker知道映射输出和主机之间的映射。 reducer中的一个线程会定期向主服务器询问地图输出主机,直到它们全部检索到它们为止。
如果映射输出足够小(映射输出的大小由mapred.job.shuffle.input.buffer.percent控制,它指定用于此目的的堆的比例) );否则,它们被复制到磁盘。当内存缓冲区达到阈值大小(由mapred.job.shuffle.merge.percent控制)或达到阈值数量的映射输出(mapred.inmem.merge.threshold)时,它将合并并溢出到磁盘。如果指定了组合器,它将在合并期间运行,以减少写入磁盘的数据量。
当副本在磁盘上累积时,后台线程会将它们合并为更大的已排序文件。这节省了一些时间合并。请注意,必须在内存中解压缩(通过map任务)压缩的任何地图输出,以便对它们执行合并。
当复制了所有地图输出后,reduce任务进入排序阶段(应该正确地称为合并阶段,因为排序是在地图侧执行的),它合并了地图输出,维护它们排序。这是轮次完成的。例如,如果有50个地图输出且合并系数为10(默认值,由io.sort.factor属性控制,就像在地图的合并中一样),则会有五轮。每轮将10个文件合并为一个,所以最后会有5个中间文件。
合并不是将最后一轮合并这五个文件合并到一个排序文件中,而是通过直接在最后阶段(reduce阶段)中提供reduce函数来保存到磁盘的行程。最后的合并可以来自内存和磁盘段的混合。
答案 1 :(得分:1)
如果我们配置了多个reducer,那么在分区期间如果我们获得不同reducer的密钥,它们将存储在与reducer相对应的单独文件中,并且在map任务结束时,完成文件将发送到reducer而不是单个key
答案 2 :(得分:1)
说,你有3个减速器在运行。然后,您可以使用分区程序来决定将哪些键转到三个reducer中的哪一个。你可以在分区器中做一个X%3来决定哪个键去哪个reducer。默认情况下,Hadoop使用HashPartitioner.