MapReduce中的分区如何正常工作?

时间:2013-07-18 21:42:55

标签: hadoop mapreduce

我认为我对MapReduce编程模型有一般的理解,但即使在阅读了原始论文和其他一些资料之后,我也不清楚许多细节,特别是关于中间结果的划分。

到目前为止,我将快速总结一下我对MapReduce的理解:我们有一个可能非常大的输入数据集,它由MR-Framework自动分成M个不同的部分。对于每个部分,框架调度一个映射任务,该任务由我的集群中的一个可用处理器/机器执行。 M个映射任务中的每一个输出一组键值对,其本地存储在执行该映射任务的同一机器上。每台机器将其磁盘划分为R个分区,并根据分区之间的中间密钥分配其计算的中间密钥值对。然后,框架为每个不同的中间密钥启动一个reduce任务,该任务再次由任何可用的机器执行。

现在我的问题是:

  1. 在某些教程中,听起来可能会有并行执行的map和reduce任务。这是正确的吗?怎么可能,假设每个不同的中间密钥只开始一个reduce任务?在我们开始第一个reduce任务之前,我们不必等到最后一个map任务完成吗?
  2. 由于每个不同的中间密钥有一个reduce任务,每个reduce任务是否需要执行机器从其他每台机器加载相应的分区?潜在地,每台机器都可以具有带有所需中间密钥的键值对,因此对于每个reduce任务,我们可能必须查询所有其他机器。这真的很有效吗?
  3. 原始论文说分区数(R)由用户指定。但是不是分区输入的减少任务吗?或者更确切地说:在一台减少任务的输入中,并非所有机器中具有相同编号的所有分区的并集?这意味着,R取决于用户通常不知道的不同中间密钥的数量。
  4. 从概念上讲,很清楚地图的输入和输出以及减少功能/任务是什么。但我认为我还没有在技术层面上理解MapReduce。有人可以帮我理解吗?

2 个答案:

答案 0 :(得分:11)

  1. 您可以在地图任务仍在运行时启动减速器任务(使用称为慢启动的功能),但减速器只能运行复制阶段(从已完成的地图任务中获取已完成的结果。需要等待在所有映射器实际执行最终排序并减少之前完成所有映射器。
  2. reduce任务实际上处理零个,一个或多个键(而不是每个键的离散任务)。在对这些中间输出进行排序之前,每个reducer将需要从每个与其分区相关的map任务中获取map输出,然后一次减少一个键集。
  3. 返回2中的注释 - reducer任务(每个分区一个)在零,一个或多个键上运行,而不是每个离散键的单个任务。
  4. 了解中间密钥的扩展和变化也很重要,因为它是经过散列和模数化(如果使用默认的HashPartitioner)来确定哪个reduce分区应该处理该密钥。假设您有偶数个reducer任务(10),并且输出键总是哈希到偶数 - 那么在这种情况下,这些哈希数字的模数和10将始终是偶数,这意味着奇数编号的减速器将从不处理任何数据。

答案 1 :(得分:7)

克里斯所说的附录,

基本上,Hadoop中的分区器类(例如,默认HashPartitioner

必须实现此功能,

int getPartition(K key, V value, int numReduceTasks) 

此功能负责返回分区编号,并从 numReduceTasks 变量中获取您在启动作业时修复的缩减器数量,如HashPartitioner中所示。

根据上述函数返回的整数,Hadoop选择应该运行特定键的reduce任务的节点。

希望这有帮助。