在 Hadoop 中,reduce 任务什么时候开始?它们是否在映射器完成一定百分比(阈值)后开始?如果是这样,这个阈值是固定的吗?通常使用什么样的阈值?
8 回答
reduce阶段有3个步骤:shuffle、sort、reduce。Shuffle 是 reducer 从每个 mapper 收集数据的地方。这可能在映射器生成数据时发生,因为它只是数据传输。另一方面,排序和归约只能在所有映射器完成后开始。你可以通过查看 reducer 完成百分比来判断 MapReduce 在做什么:0-33% 表示它在做 shuffle,34-66% 是 sort,67%-100% 是 reduce。这就是为什么你的 reducer 有时会“卡”在 33% 的原因——它正在等待映射器完成。
减速器根据已完成映射器的百分比阈值开始洗牌。您可以更改参数以使减速器迟早启动。
为什么提早启动减速器是件好事?因为它随着时间的推移分散了从映射器到减速器的数据传输,如果您的网络是瓶颈,这是一件好事。
为什么提早启动减速器是一件坏事?因为他们“占用”减少了插槽,而只复制数据并等待映射器完成。稍后开始的另一项实际使用 reduce 插槽的作业现在无法使用它们。
mapred.reduce.slowstart.completed.maps
您可以通过更改in的默认值来自定义减速器何时启动mapred-site.xml
。值1.00
将等待所有映射器完成,然后再启动减速器。的值0.0
将立即启动减速器。当一半的映射器完成时,一个值0.5
将启动减速器。您也可以mapred.reduce.slowstart.completed.maps
根据工作进行更改。在新版本的 Hadoop(至少 2.4.1)中,该参数称为 ismapreduce.job.reduce.slowstart.completedmaps
(感谢用户 yegor256)。
通常,如果系统同时运行多个作业,我喜欢保持mapred.reduce.slowstart.completed.maps
在上面。0.9
这样,当他们除了复制数据什么都不做时,这项工作就不会占用减速器。如果您一次只运行一项工作,那么做0.1
可能是合适的。
reduce 阶段可以在调用 reducer 之前很久开始。一旦“a”映射器完成工作,生成的数据就会经历一些排序和改组(包括对组合器和分区器的调用)。减速器“阶段”在映射器数据处理开始的那一刻开始。完成这些处理后,您将看到减速器百分比的进展。但是,还没有调用任何减速器。根据可用/使用的处理器数量、数据性质和预期减速器的数量,您可能希望按照上面@Donald-miner 的描述更改参数。
据我了解,Reduce 阶段从地图阶段开始,并继续使用地图中的记录。然而,由于在 map 阶段之后有排序和洗牌阶段,所有的输出都必须被排序并发送到 reducer。因此,从逻辑上讲,您可以想象 reduce 阶段仅在 map 阶段之后开始,但实际上出于性能原因,reducer 也使用映射器进行初始化。
Reduce 仅在所有映射器完成任务后才开始,Reducer 必须与所有映射器通信,因此它必须等到最后一个映射器完成其任务。然而,映射器在完成任务时开始传输数据。
reduce 阶段显示的百分比实际上是从 maps 输出复制到 reducers 输入目录的数据量。要知道这个复制什么时候开始?这是您可以设置的配置,如 Donald 上面所示。一旦所有数据都被复制到减速器(即 100% 减少),这就是减速器开始工作的时候,因此如果您的减速器代码是 I/O 或 CPU 密集型的,则可能会冻结在“100% 减少”中。
考虑一个 WordCount 示例,以便更好地理解 map reduce 任务的工作原理。假设我们有一个大文件,比如一本小说,我们的任务是找出每个单词在文件中出现的次数。由于文件很大,它可能被分成不同的块并在不同的工作节点中复制。字数统计作业由 map 和 reduce 任务组成。map 任务将每个块作为输入,并生成一个中间键值对。在这个例子中,由于我们正在计算单词的出现次数,因此映射器在处理块时会产生形式为 (word1,count1)、(word2,count2) 等形式的中间结果。所有映射器的中间结果是通过了一个洗牌阶段,该阶段将重新排序中间结果。
假设我们来自不同映射器的地图输出具有以下形式:
地图 1:- (is,24) (was,32) (and,12)
Map2 :- (my,12) (is,23) (was,30)
map 输出以这样的方式排序,即相同的键值被赋予相同的 reducer。这意味着对应于 is,was 等的键使用相同的减速器。它是产生最终输出的减速器,在这种情况下为:- (and,12)(is,47)(my,12 )(是,62)
Reducer 任务仅在completion
所有映射器结束后才开始。
但是数据传输发生在each
Map 之后。实际上这是一个拉动操作。
这意味着,每次 reducer 都会询问每个 maptask 是否有一些数据要从 Map 中检索。如果他们发现任何 mapper 完成了他们的任务,Reducer 会拉取中间数据。
来自 Mapper 的中间数据存储在disk
. 并且从 Mapper 到 Reduce 的数据传输是通过网络发生的(Data Locality
在 Reduce 阶段不保留)
当 Mapper 完成其任务时,Reducer 开始其作业以减少数据,这是 Mapreduce 作业。